[英]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.