为啥 `async/await` 在我的情况下不起作用?
Posted
技术标签:
【中文标题】为啥 `async/await` 在我的情况下不起作用?【英文标题】:Why `async/await` doesn't work in my case?为什么 `async/await` 在我的情况下不起作用? 【发布时间】:2018-07-15 00:13:06 【问题描述】:我读到了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
?
【问题讨论】:
异步函数是 ES2017 的一部分,而不是 ES7 (ES2016)。 @FelixKling,谢谢,我很困惑,ES2017
是不是叫ES8
?
【参考方案1】:
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');
【讨论】:
【参考方案2】:因为setTimeout
不返回承诺。 await x
仅在 x
是一个承诺时等待;如果x
不是一个承诺,它(有效地)包裹在一个中,就好像你有await Promise.resolve(x)
。这意味着它后面的代码将尽快异步运行。*
如果您想要setTimeout
的承诺版本,请参阅this question's answers。但即便如此,您的 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)
之前,因为在任务期间安排的承诺回调发生在该任务结束之后,在从队列中提取下一个任务之前(甚至如果下一个任务是在 promise 回调之前安排的)。更多关于这个(“宏任务”和“微任务”)在this question's answers。
【讨论】:
【参考方案3】:您可以await
到返回Promise
的函数。 setTimeout
不返回 Promise
。所以在这种情况下await
在setTimeout
之前使用是没有意义的。
您可以将您的 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');
)();
【讨论】:
以上是关于为啥 `async/await` 在我的情况下不起作用?的主要内容,如果未能解决你的问题,请参考以下文章
.push() 在 throw 下不起作用,使用 async await 方法在 javascript 中循环获取数据
Gulp/Typescript/Async/Await 代码不起作用 - 为啥?
为啥 selectAnnotation 在这种情况下不起作用?