与 Promises 相比,异步功能
async
功能不替代 Promise
类型; 他们添加语言关键字,使承诺更容易调用。它们是可以互换的:
async function doAsyncThing() { ... }
function doPromiseThing(input) { return new Promise((r, x) => ...); }
// Call with promise syntax
doAsyncThing()
.then(a => doPromiseThing(a))
.then(b => ...)
.catch(ex => ...);
// Call with await syntax
try {
const a = await doAsyncThing();
const b = await doPromiseThing(a);
...
}
catch(ex) { ... }
任何使用 promises 链的函数都可以使用 await
重写:
function newUnicorn() {
return fetch('unicorn.json') // fetch unicorn.json from server
.then(responseCurrent => responseCurrent.json()) // parse the response as JSON
.then(unicorn =>
fetch('new/unicorn', { // send a request to 'new/unicorn'
method: 'post', // using the POST method
body: JSON.stringify({unicorn}) // pass the unicorn to the request body
})
)
.then(responseNew => responseNew.json())
.then(json => json.success) // return success property of response
.catch(err => console.log('Error creating unicorn:', err));
}
可以使用 async
/ await
重写该功能,如下所示:
async function newUnicorn() {
try {
const responseCurrent = await fetch('unicorn.json'); // fetch unicorn.json from server
const unicorn = await responseCurrent.json(); // parse the response as JSON
const responseNew = await fetch('new/unicorn', { // send a request to 'new/unicorn'
method: 'post', // using the POST method
body: JSON.stringify({unicorn}) // pass the unicorn to the request body
});
const json = await responseNew.json();
return json.success // return success property of response
} catch (err) {
console.log('Error creating unicorn:', err);
}
}
newUnicorn()
的 async
变种似乎返回了 Promise
,但实际上有多个 await
关键字。每个人都返回了一个 Promise
,所以我们真的有一系列的承诺而不是链条。
事实上,我们可以把它想象成一个 function *
发电机,每个 await
都是一个 yield new Promise
。但是,下一个继续该功能需要每个承诺的结果。这就是为什么函数需要额外的关键字 async
(以及调用 promises 时的 await
关键字),因为它告诉 Javascript 自动为此迭代创建一个观察者。当此迭代完成时,async function newUnicorn()
返回的 Promise
将解析。
实际上,你不需要考虑那个; await
隐藏了承诺,而 async
隐藏了生成器迭代。
你可以将 async
函数称为承诺,以及 await
任何承诺或任何 async
函数。你不需要 await
一个异步函数,就像你可以在没有 .then()
的情况下执行一个承诺一样。
如果要立即执行该代码,也可以使用 async
IIFE :
(async () => {
await makeCoffee()
console.log('coffee is ready!')
})()