Poy*_*man 6 javascript promise async-await
我想知道,如果等待已解决的承诺,将导致同步代码执行或可能导致异步代码执行。
我制作了这个小片段来检查浏览器:
const promise = new Promise((resolve) => {
console.log('exec promise');
setTimeout(() => {
console.log('executed promise');
resolve();
}, 1000);
});
(async () => {
console.log('start');
for (let i = 0; i < 1e8; i += 1) {
await promise;
}
console.log('end');
})();
Run Code Online (Sandbox Code Playgroud)
看起来浏览器使其同步(考虑到屏幕冻结)。
但是......这是由于浏览器特定的实现吗?还是设计使然?
这是一个替代演示,它不会冻结浏览器(我认为这妨碍了我们想要展示的内容),并且显示了与您最初的结论相反的行为:
const p = new Promise((r) => r());
p.then(() => {
(async() => {
console.log('a');
await p;
console.log('p');
})()
console.log('b');
});Run Code Online (Sandbox Code Playgroud)
在这种情况下,我们得到了p,一个已解决的承诺。然后我们启动一个等待它的异步函数。输出是:
ab
p
即,当异步函数击中已解决的b时,它仍然返回控制权(并被记录)。只有在被记录之后,事件循环才可以在随后被记录之后返回执行。awaitpbawaitp
这是标准行为吗?是的。
该规范有效地将等待的表达式转变为thenPromise 的一部分,并在后续步骤的步骤 9 和 10 中决定如何继续。
- 如果 Promise.[[PromiseState]] 处于待处理状态,则
a. 将 fillReaction 附加为 List 的最后一个元素,即 Promise.[[PromiseFulfillReactions]]。
b. 将rejectReaction 附加为List 的最后一个元素,即promise.[PromiseRejectReactions]]。- 否则,如果 Promise.[[PromiseState]] 得到满足,
则 a. 然后设值为promise.[[PromiseResult]]。
b. 令fulfillJob 为NewPromiseReactionJob(fulfillReaction, value)
c.执行 HostEnqueuePromiseJob(fulfillJob.[[Job]],fulfillJob.[[Realm]])。
步骤 9 表示如果它处于待处理状态,则将生成的内容添加then到承诺完成时要调用的事物列表中。
步骤 10 触及您问题的核心 - 它表示如果已经完成,则将作业排队 - 即将其放置在要回调的事物队列中。
该规范实际上表明 anawait永远不应该同步返回。
| 归档时间: |
|
| 查看次数: |
5484 次 |
| 最近记录: |