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