请教一个promise执行顺序的问题,有关resolve一个promise以及注册callback的顺序
发布于 6 年前 作者 StudentWan 3692 次浏览 来自 问答
const original = Promise.resolve(2)
new Promise((resolve) => {
	resolve(original);
	Promise.resolve().then(() => Promise.resolve().then(() => console.log(1)))
	console.log(4)
}).then(t => console.log(t))
console.log(3)

这样一段代码. 按照我的理解 因为original已经被resolve,所以它的状态被new Promise继承 然后执行Promise.resolve并注册回调 然后打印4 然后注册new Promise的回调 然后打印3 然后执行第一个注册的回调,并注册第三个回调 然后打印t,也就是2 然后执行第三个回调,也就是1

可是执行结果却是4,3,1,2 想不通为什么,特来求教! 谢谢各位大牛~~~

13 回复
// var original = Promise.resolve(2)
new Promise((resolve) => {
  resolve(2); // 这里直接resolve(2)的话就是4 3 2 1了
  Promise.resolve().then(() => {
    return Promise.resolve().then(() => {
      console.log(1)
    })
  })
  console.log(4)
}).then(t => console.log(t))
console.log(3)

大半夜地想了半天,还是觉得想不通,等后面的答案吧。。。

@stop2stare 是的 非常费解😂 自豪地采用 CNodeJS ionic

找了很久没有找到他的数组,但是根据 https://www.promisejs.org/implementing/ 的实现,假如是一个 promise,那么会推进到他的 handlers 数组里面.

image.png

不知道这样你们能不能理解,micotask 会在下一次轮蓄之前,而 then 是 FIFO,callback 里面是同步的,所以里面的 then 会先进入。

而且这个是深度优先的。

image.png

你预期想得到的应该是这个吧。

image.png

@MiYogurt 你好 这似乎是一个规范里没有提到的问题。 不同的实现处理方式也有不同,bluebird在executor里的resolve是同步执行的,而V8在处理这个resolve一个promise时似乎是先将这个resolve加入到microtask queue里的,目前我比较认可这种看法。

讨论请看:v2ex

@StudentWan 我看了V站上的解释,看到有点生理不适。保命要紧,我先撤了。

@stop2stare 为何会生理不适😂 自豪地采用 CNodeJS ionic

@StudentWan 嗯,看到胃不舒服。。。

为何我 node 8.9.3 是 4 3 2 1 chrome 64 也是 4 3 2 1 ? 咱们玩的不是同一个?

@StudentWan 你用script标签运行看看

@5196666qwe 真有意思。。。

@StudentWan 还有个更有意思的,你用cmd执行和vscode debug也会出现两种结果。

来自酷炫的 CNodeMD

1,2 从理论上比较不出来谁先出来,不然就要背诵了,哈哈

回到顶部