为了账号安全,请及时绑定邮箱和手机立即绑定

Javascript:等待已解决的承诺

Javascript:等待已解决的承诺

海绵宝宝撒 2023-05-11 16:33:08
我想知道,如果等待已解决的承诺,将导致同步代码执行或可能导致异步代码执行。我做了这个小片段来检查浏览器: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');})();看起来浏览器使其同步(考虑到屏幕冻结)。但是......是由于浏览器特定的实现吗?还是设计使然?
查看完整描述

2 回答

?
慕田峪4524236

TA贡献1875条经验 获得超5个赞

这是一个不会冻结浏览器的替代演示(我认为这是我们试图展示的方式),它显示了与您最初的结论相反的行为:


const p = new Promise((r) => r());


p.then(() => {


  (async() => {

    console.log('a');

    await p;

    console.log('p');

  })()

  console.log('b');


});

在这种情况下,我们得到p一个已解决的承诺。然后我们启动一个等待它的异步函数。输出是:

一个
bp
_

IE 异步函数在点击已经解析的b时仍然返回控制权(并被记录)。只有在被记录之后,事件循环才可以自由地返回到随后被记录之后的执行。awaitpbawaitp

这是标准行为吗?是的。

该规范有效地将等待的表达式转换为then承诺的一部分,并在后续步骤的第 9 步和第 10 步中决定如何进行。

  1. 如果 promise.[[PromiseState]] 处于待定状态,则
    a. 将 fulfillReaction 添加为列表的最后一个元素,即 promise.[[PromiseFulfillReactions]]。
    b. 附加 rejectReaction 作为 List 的最后一个元素,即 promise.[PromiseRejectReactions]]。

  2. 否则如果 promise.[[PromiseState]] 被履行,
    a。然后让价值成为承诺。[[PromiseResult]]。
    b. 设 fulfillJob 为 NewPromiseReactionJob(fulfillReaction, value)
    c。执行 HostEnqueuePromiseJob(fulfillJob.[[Job]], fulfillJob.[[Realm]])。

第 9 步表示如果它处于待处理状态,则将生成的添加到then承诺履行时要调用的事物列表中。

第 10 步是您问题的核心——它说如果它已经完成,则将作业排入队列——即将它放在要回调的队列中。

规范有效地说明了 anawait永远不应该同步返回。


查看完整回答
反对 回复 2023-05-11
?
陪伴而非守候

TA贡献1757条经验 获得超8个赞

这是预期的行为。您在那里冻结了事件循环,因为承诺已经解决,下一个 await 运算符将在事件循环的同一迭代中等待并解决下一个承诺描述符。但这种行为可能是特定于平台的,具体取决于您实际使用的是哪种 promise 实现 - 本机或 shim。


const promise= Promise.resolve();


(async()=>{

    for(let i=0; i< 10000000; i++) {

        await promise;

    }

    console.log('end');

})()


setTimeout(()=> console.log('nextEventLoopTick'), 0);

会输出如下:


end

nextEventLoopTick

如您所见,async fn 将在 setTimeout 之前完全解析。因此,这表明异步函数是在同一个事件循环滴答上解析的。


查看完整回答
反对 回复 2023-05-11
  • 2 回答
  • 0 关注
  • 126 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信