await
åºçº¿
广æ³å¯ç¨
*
èª 2017å¹´3æ èµ·ï¼æ¤ç¹æ§å·²å¨ä¸»æµæµè§å¨ä¸å¾å°æ¯æï¼å¯å¨å¤§å¤æ°è®¾å¤åæµè§å¨çæ¬ä¸æ£å¸¸ä½¿ç¨ã
* æ¤ç¹æ§çæäºé¨åçæ¯æç¨åº¦å¯è½ææä¸åã
await æä½ç¬¦ç¨äºçå¾
ä¸ä¸ª Promise å
ç°å¹¶è·åå®å
ç°ä¹åçå¼ãå®åªè½å¨å¼æ¥å½æ°æè
模åé¡¶å±ä¸ä½¿ç¨ã
è¯æ³
await expression;
åæ°
expression-
è¦çå¾ ç
Promiseå®ä¾ï¼Thenable å¯¹è±¡ï¼æä»»æç±»åçå¼ã
è¿åå¼
è¿åä» Promise å®ä¾æ thenable 对象åå¾çå¤çç»æã妿çå¾
çå¼ä¸ç¬¦å thenableï¼åè¿åè¡¨è¾¾å¼æ¬èº«çå¼ã
å¼å¸¸
æç»ï¼rejectï¼çåå ä¼è¢«ä½ä¸ºå¼å¸¸æåºã
æè¿°
await é常ç¨äºæå¼ promise çå
è£
ï¼ä½¿ç¨æ¹æ³æ¯ä¼ éä¸ä¸ª Promise ä½ä¸º expressionãä½¿ç¨ await æ»ä¼æåå½å弿¥å½æ°çæ§è¡ï¼å¨è¯¥ Promise æ²å®ï¼settledï¼æå
ç°ææç»ï¼åç»§ç»æ§è¡ã彿°çæ§è¡æ¢å¤ï¼resumeï¼æ¶ï¼await 表达å¼çå¼å·²ç»åæäº Promise å
ç°çå¼ã
è¥è¯¥ Promise 被æç»ï¼rejectedï¼ï¼await 表达å¼ä¼ææç»çåå ï¼reasonï¼æåºãå½å彿°ï¼await æå¨ç彿°ï¼ä¼åºç°å¨æåºçéè¯¯çæ è¿½è¸ªï¼stack traceï¼ï¼å¦åå½å彿°å°±ä¸ä¼å¨æ 追踪åºç°ã
await æ»ä¼åæ¥å°å¯¹è¡¨è¾¾å¼æ±å¼å¹¶å¤çï¼å¤ççè¡ä¸ºä¸ Promise.resolve() ä¸è´ï¼ä¸å±äºåç Promise çå¼å
¨é½ä¼è¢«éå¼å°è½¬æ¢ä¸º Promise å®ä¾åçå¾
ãå¤ççè§å为ï¼è¥è¡¨è¾¾å¼ï¼
- æ¯ä¸ä¸ªåç
Promiseï¼åçPromiseçå®ä¾æå ¶æ´¾çç±»çå®ä¾ï¼ä¸æ»¡è¶³expression.constructor === Promiseï¼ï¼ä¼è¢«ç´æ¥ç¨äºçå¾ ï¼çå¾ ç±åç代ç å®ç°ï¼è¯¥å¯¹è±¡çthen()ä¸ä¼è¢«è°ç¨ã - æ¯ thenable 对象ï¼å
æ¬éåçç
Promiseå®ä¾ãpolyfillãProxyãæ´¾çç±»çï¼ï¼ä¼æé ä¸ä¸ªæ°Promiseç¨äºçå¾ ï¼æé æ¶ä¼è°ç¨è¯¥å¯¹è±¡çthen()æ¹æ³ã - 䏿¯ thenable 对象ï¼ä¼è¢«å
è£
è¿ä¸ä¸ªå·²å
ç°ç
Promiseç¨äºçå¾ ï¼å ¶ç»æå°±æ¯è¡¨è¾¾å¼çå¼ã
示ä¾
>çå¾ Promise çå ç°
å½ä¸ä¸ª Promise è¢«ä¼ éç» await æä½ç¬¦ï¼await å°çå¾
该 Promise å
ç°ï¼å¹¶å¨å
ç°åè¿å该 Promise å
ç°çå¼ã
function resolveAfter2Seconds(x) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}
async function f1() {
let x = await resolveAfter2Seconds(10);
console.log(x); // 10
}
f1();
转æ¢ä¸º promise
è¥è¡¨è¾¾å¼çå¼ä¸æ¯ Promiseï¼await ä¼æè¯¥å¼è½¬æ¢ä¸ºå·²å
ç°ç Promiseï¼ç¶åè¿åå
¶ç»æã
async function f3() {
const y = await 20;
console.log(y); // 20
const obj = {};
console.log((await obj) === obj); // true
}
f3();
promise 被æç»
妿 Promise 被æç»ï¼åæåºæç»çåå ã
async function f4() {
try {
const z = await Promise.reject(30);
} catch (e) {
console.error(e); // 30
}
}
f4();
å¤ç被æç»ç promise
ä½ å¯ä»¥é¾å¼è°ç¨ catch()ï¼è䏿¯ä½¿ç¨ tryï¼ä»¥å¨çå¾
promise å
ç°ä¹åå¤ç被æç»ç promiseã
const response = await promisedFunction().catch((err) => {
console.error(err);
return "default response";
});
// response will be "default response" if the promise is rejected
å¨é¡¶å±ä½¿ç¨ await
卿¨¡åçé¡¶å±ï¼ä½ å¯ä»¥åç¬ä½¿ç¨å
³é®å awaitï¼å¼æ¥å½æ°çå¤é¢ï¼ãä¹å°±æ¯è¯´ä¸ä¸ªæ¨¡å妿å
å«ç¨äº await ç忍¡åï¼è¯¥æ¨¡åå°±ä¼çå¾
è¯¥åæ¨¡åï¼è¿ä¸è¿ç¨å¹¶ä¸ä¼é»å¡å
¶ä»å模åã
ä¸é¢æ¯ä¸ä¸ªå¨ export 表达å¼ä¸ä½¿ç¨äº Fetch API çä¾åã任使件åªè¦å¯¼å
¥è¿ä¸ªæ¨¡åï¼åé¢ç代ç å°±ä¼çå¾
ï¼ç´å° fetch 宿ã
// fetch request
const colors = fetch("../data/colors.json").then((response) => response.json());
export default await colors;
await 对æ§è¡è¿ç¨çå½±å
å½å½æ°æ§è¡å° await æ¶ï¼è¢«çå¾
ç表达å¼ä¼ç«å³æ§è¡ï¼ææä¾èµè¯¥è¡¨è¾¾å¼çå¼ç代ç ä¼è¢«æåï¼å¹¶æ¨éè¿å¾®ä»»å¡éåï¼microtask queueï¼ãç¶å主线ç¨è¢«éæ¾åºæ¥ï¼ç¨äºäºä»¶å¾ªç¯ä¸çä¸ä¸ä¸ªä»»å¡ãå³ä½¿çå¾
ç弿¯å·²ç»æ²å®ç promise æä¸æ¯ promiseï¼ä¹ä¼åçè¿ç§æ
åµãä¾å¦ï¼èè以ä¸ä»£ç ï¼
async function foo(name) {
console.log(name, "start");
console.log(name, "middle");
console.log(name, "end");
}
foo("First");
foo("Second");
// First start
// First middle
// First end
// Second start
// Second middle
// Second end
对åºå° Promise çåæ³æ¯ï¼
function foo(name) {
return new Promise((resolve) => {
console.log(name, "start");
console.log(name, "middle");
console.log(name, "end");
resolve();
});
}
æ§è¡å° await æ¶ï¼åé¢ç代ç 就伿´ä½è¢«å®æè¿ä¸ä¸ªæ°ç微任å¡ï¼æ¤åç彿°ä½åä¸ºå¼æ¥æ§è¡ã
async function foo(name) {
console.log(name, "start");
await console.log(name, "middle");
console.log(name, "end");
}
foo("First");
foo("Second");
// First start
// First middle
// Second start
// Second middle
// First end
// Second end
对åºç Promise åæ³æ¯ï¼
function foo(name) {
return new Promise((resolve) => {
console.log(name, "start");
resolve(console.log(name, "middle"));
}).then(() => {
console.log(name, "end");
});
}
è½ç¶è¿éç then() çèµ·æ¥å¾å¤ä½ï¼å
¶ä¸ç代ç å®å
¨å¯ä»¥è¢«åå¹¶å°æé å¨çåè°éï¼ä½ä¸ç®¡è¯¥ Promise çç¶æå¦ä½ï¼then() çåè°æ»ä¼è¢«å¼æ¥æ§è¡ï¼await çè¡ä¸ºä¹ä¸æ ·ãå æ¤ï¼åªè¦æ
åµä¸æ¯å¿
é¡»æå¯è½éè¦çå¾
Promise çç»æï¼å°±åºè¯¥é¿å
ä½¿ç¨ awaitã
å ¶ä»å¾®ä»»å¡è½å¨å½æ°æ§è¡æ¢å¤ä¹åæ§è¡ï¼
let i = 0;
queueMicrotask(function test() {
i++;
console.log("microtask", i);
if (i < 3) {
queueMicrotask(test);
}
});
(async () => {
console.log("async function start");
for (let i = 1; i < 3; i++) {
await null;
console.log("async function resume", i);
}
await null;
console.log("async function end");
})();
queueMicrotask(() => {
console.log("queueMicrotask() after calling async function");
});
console.log("script sync part end");
// Logs:
// async function start
// script sync part end
// microtask 1
// async function resume 1
// queueMicrotask() after calling async function
// microtask 2
// async function resume 2
// microtask 3
// async function end
æ¤æ¡ä¾ä¸ï¼test() æ»ä¼å¨å¼æ¥å½æ°æ¢å¤æ§è¡å被è°ç¨ï¼åç°è½®æµçè°åº¦ã微任å¡è¢«æ§è¡ç顺åºé常就æ¯å
¥éçå
å顺åºï¼è console.log("queueMicrotask() after calling async function"); æ¯ await æå
¥éï¼å æ¤ "queueMicrotask() after calling async function" å¨å¼æ¥å½æ°ç¬¬ä¸æ¬¡æ¢å¤ä¹åæè¾åºã
æ¹åæ 追踪
ææ¶ï¼å½å¼æ¥å½æ°ç´æ¥è¿åä¸ä¸ª Promise æ¶æä»¬ä¼çç¥ awaitã
async function noAwait() {
// Some actions...
return /* await */ lastAsyncTask();
}
使¯åå¦è¿ä¸ª Promise çç±æ¥æ¯è°ç¨äºå¼æ¥å½æ°ï¼ä¸è¯¥å¼æ¥å½æ°ç弿¥é¨åæåºäºé误ï¼
async function lastAsyncTask() {
await null;
throw new Error("failed");
}
async function noAwait() {
return lastAsyncTask();
}
noAwait();
// Error: failed
// at lastAsyncTask
æ 追踪ä¸åªåºç°äº lastAsyncTaskï¼è¿æ¯å 为æåºéè¯¯æ¶ noAwait å·²ç»è¿åââæç§æä¹ä¸è¯¥ Promise å·²ç»ä¸ noAwait æ å
³ãè¥è¦æ¹åæ 追踪ï¼ä½ å¯ä»¥ç¨ await æåçå¾
ï¼é误就ä¼å¨å½æ°ä½ç»æåæåºï¼æ¥ç该é误ä¼è¢«å
è£
è¿ä¸ä¸ªæ°ç Promiseï¼å é误被 await å¨ä¸»è°å½æ°ç彿°ä½æåºï¼ä¸»è°å½æ°å°ä¼åºç°å¨æ 追踪ã
async function lastAsyncTask() {
await null;
throw new Error("failed");
}
async function withAwait() {
return await lastAsyncTask();
}
withAwait();
// Error: failed
// at lastAsyncTask
// at async withAwait
使¯ï¼è¿æ ·ä¼æä¸ç¹æ§è½çºç²ï¼æ¯ç« Promise ä¼è¢«æè£
äºå忬¡å
è£
ã
è§è
| è§è |
|---|
| ECMAScript® 2027 Language Specification > # sec-async-function-definitions > |
æµè§å¨å ¼å®¹æ§
åè§
async 彿°async 彿°è¡¨è¾¾å¼AsyncFunction对象- v8.dev ä¸ç Top level await