[英]Why `async/await` doesn't work in my case?
我讀過async/await
,但我有一個關鍵問題。 首先,我解釋了一個舊示例以顯示我的問題的基礎,然后我問了我的確切問題。
大家都知道:
console.log('1');
console.log('2');
console.log('3'); // Ex: 123
這很簡單,但在以下情況下:
console.log('1');
setTimeout(()=>{
console.log('2');
},0);
console.log('3'); // Ex: 132
也很簡單, setTimeout
函數是asynchronous
, JavaScript
從中跳轉,解析后運行它的函數,所以我們在1
和3
之后看到2
。
但是,現在我讀了async/await
並寫了一個這樣的函數:
(async function test() {
console.log('1');
await setTimeout(()=>{
console.log('2');
},0);
console.log('3');
})(); // Ex: 132
出口也是132
,為什么? 這是我的問題,為什么3
在2
之前運行? 我期望因為async/await
之后1
JavaScript 等待2
然后寫入3
。 為什么是132
?
await
僅在傳遞給它的值是Promise
時掛起。 在您的情況下, setTimeout
返回一個Number
因此 await 不會等待它。
正確的代碼如下:
async function test() {
console.log('1');
await new Promise((resolve, reject) => {
setTimeout(() => {
console.log('2');
resolve()
}, 0);
});
console.log('3');
}
因為setTimeout
不返回承諾。 await x
僅在x
是承諾時才等待; 如果x
不是承諾,它(有效地)包裝在一個中,就像你有await Promise.resolve(x)
。 這意味着它后面的代碼將異步運行,但會盡快運行。*
如果您想要setTimeout
的承諾版本,請參閱此問題的答案。 但即便如此,您的test
函數也不會使用回調,而只需等待啟用承諾的超時:
function later(delay) { return new Promise(function(resolve) { setTimeout(resolve, delay); }); } async function test() { console.log("1"); await later(10); console.log("2"); console.log("3"); } test().catch(e => console.error(e)); console.log("After the call (just to prove it does wait for the timeout after 1 and before 2");
* 在瀏覽器上,這保證在同一任務期間安排的setTimeout(..., 0)
之前,因為在任務期間安排的承諾回調發生在該任務結束之后,在從隊列中提取下一個任務之前(即使下一個任務是在承諾回調之前安排的)。 在這個問題的答案中更多關於這個(“宏任務”和“微任務”)。
您可以await
返回Promise
函數。 setTimeout
不返回Promise
。 所以在這種情況下,在setTimeout
之前使用await
是沒有意義的。
你可以將你的setTimeout
包裝成一個 Promise 並在setTimeout
函數中調用 resolve。
(async function test() { console.log('1'); await new Promise((resolve, reject) => { setTimeout(() => { console.log('2'); resolve(); // also can pass a parameter here to get it via await. },0); }); console.log('3'); })();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.