2017-09-16 55 views
0

我有这段代码:承诺解析顺序伺机

af = async() => { 
 
    Promise.resolve() 
 
    .then(x => console.log("first then")) 
 
    .then(x => console.log("second then")) 
 
    await Promise.resolve() 
 
    console.log("after await") 
 
} 
 

 
af()

在谷歌的Chrome版本61.0.3163.91(正式版本)(64位) 当我运行它从一个<script>,我得到了以下结果:

first then 
after await 
second then 

但是当我复制/粘贴代码到控制台,并运行它有:

first then 
second then 
after await 

node.js 8.5.0的行为相似。

什么是正确的顺序和为什么有区别?

//编辑

另一个有趣的事情是,火狐55.0.2(64位) 此代码:

af = async() => { 
 
    Promise.resolve() 
 
    .then(x => console.log("first then")) 
 
    .then(x => console.log("second then")) 
 
    .then(x => console.log("third then")) 
 
    .then(x => console.log("forth then")) 
 
    await Promise.resolve() 
 
    console.log("after await") 
 
} 
 

 
af()

日志:

first then 
second then 
third then 
after await 
forth then 
+0

如果多个'。然后()'处理程序都在一个'await'后同时事项的队列(和代码的精确的顺序是非常相同一个'.then()'处理程序),那么你的代码应该写成你自己控制顺序,而不是完全依赖于promise调度程序的命令。而且,我甚至不确定你问的是实际写入规范。无论如何,大多数真正的实现都会有不确定时间的承诺背后的异步操作。 – jfriend00

+0

准确而精确的答案很可能会非常长,并取决于未指定的实现细节。查看DOMContentLoaded的步骤,例如https://html.spec.whatwg.org/multipage/parsing.html#the-end –

+0

不知道为什么,但它可能是一个提示: 如果您全部替换你用数组推动日志,然后登录你的最终阵列,订单总是 ['1 then','2 then','await] 也许是一个console.log不一致的行为? –

回答

0

doin的正确方法g这是在Promise.resolve()之前添加一个await,它执行“首先然后”和“然后再次”控制台日志。这样它就会等待承诺完成,然后再移到控制台日志中以便“等待”后

这就是你要这么做的方法。

af = async() => { 
 
    await Promise.resolve() // NOTE: I added a "await" before the Promise.resolve() 
 
    .then(x => console.log("first then")) 
 
    .then(x => console.log("second then")) 
 
    await Promise.resolve() 
 
    console.log("after await") 
 
} 
 

 
af()

+0

我没有要求在底部console.log之前让两个'then'都被解析。我想知道这种情况下的调度算法(在第二个'then“回调之前或之后的'await') – marzelin

+0

您是什么意思的调度算法? – user3254198

+0

支配回调添加到消息队列的顺序的规则 – marzelin