與 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!')
})()