根据 Promise A+ 规范
https://promisesaplus.com/#point-34Promise 的执行顺序是和平台相关的。promise 链的执行是在当前 event loop 的主线程结束后的某一时刻进行,具体是何时得看 js 引擎的实现或者 polyfill 的实现。( 2.2.4 )
从 v8 的实现来看,Promise 的回调是存放在 microtasks 里,event loop 会先完成 microtasks 再去执行 tasks
从 polyfill 来看,得看实现的方式。如果用 mutationObserver,会和 v8 的顺序相似。如果使用 setTimeout 或者 setImmediate,顺序就会有所不同了。总之,不同 Promise 的执行顺序并不在 Promise 的规范里,顺序也是没法保障的,只不过可以对特定情况进行分析,来了解当前 JS 解释器的执行顺序。例如我用 bulebird 的结果是 4, 3, 2, 1。
我尝试分析了一下,
:3 resolve(original)这一步在
:6 .then(t => console.log(t))
时,由于 original 是 Promise,在执行 promise resolution procedure(参考规范第 2.3 节)的时候比 resolve 非 promise 的值多了一步,需要等待被 resolve 的 promise fullfilled 或 rejected。我猜想由于是懒惰执行,所以到第 6 行 then 的时候在发现 resolve 的是一个 promise,需要等待这个 promise fullfill,于是就把:6 的 then 的回调 chain 在了 original 的后面(参考 2.3.2 )
我把格式略微优化了一下,附上 microtasks queue 的操作过程,如下图
总结来看,这种顺序是不能作为逻辑依赖的,因为规范并没有这样要求,能保证的只是每一个 chain 的顺序。
我对 v8 了解不多,所以分析过程可能不严谨,也许会有些错误,仅供参考,详细了解还得参考 promise A+和 v8 的实现。