【问题标题】:Promise.resolve vs new Promise(resolve) in vanilla jsPromise.resolve 与 vanilla js 中的新 Promise(resolve)
【发布时间】:2018-03-04 18:47:25
【问题描述】:

The relevant question 告诉我解决了一个新的承诺,即使它立即解决,它也安排在下一个循环中。但是,评论部分似乎是反例。

var p1 = Promise.resolve("p1")

/* console order will be "p2" "p1" */ 
// pattern1
// var p2 = Promise.resolve(Promise.resolve("p2")); 
// pattern2
// var p2 = Promise.resolve(new Promise(function(resolve, reject){
//   resolve("p2")
// }))

/* console order will be "p1" "p2" */ 
// pattern3
var p2 = new Promise(function(resolve, reject){
    resolve(Promise.resolve("p2"));
}) 

p2.then(function(value){
  console.log(value);
})
p1.then(function(value){
  console.log(value);
})

在 Chrome v61.0.3163.91 中很奇怪,但在 Node.js 中正常。

注意:问题与the popular one 不同。只关注顺序问题:为什么不同的模式会产生不同的顺序?最好用事件循环来解释。

【问题讨论】:

  • @JaromandaX Chromium 60 和 Firefox 57 在此处登录 "p1", "p2"
  • @JaromandaX 没有。哪一个?仍然没有收集到实际问题是什么?
  • @JaromandaX 注释代码日志导致代码被调用的顺序。是 "p1" 还是 "p2" 先记录,取决于哪个 .then() 先被调用。
  • 哦......是的......别管我的cmets,测试错误:p

标签: javascript es6-promise event-loop


【解决方案1】:

promise.then 的回调不会附加到微任务队列中,直到 promise 处于已解决(已完成或已拒绝)状态。微任务会从队列中顺序执行,即“先进先出”。

在Chrome v61.0.3163.91的实现中,一旦p1被创建,就一直处于resolved状态。模式1和模式2中的p2处于已解决状态,模式3中的p2处于待处理状态。

因此,在pattern1和pattern2中,p2.then的回调首先附加到微任务队列中,并首先执行。在pattern3中,虽然p2.then先被执行,但是由于promise仍然处于pending状态,所以它会在未来将回调追加到微任务队列中。所以p1.then的回调首先执行。

【讨论】:

    【解决方案2】:

    注释的.then()日志导致代码被调用的顺序。

    // logs `"p1"`, `"p2"`
    var p1 = Promise.resolve("p1")
    
    var p2 = Promise.resolve(Promise.resolve("p2")); 
    
    p1.then(function(value){
      console.log(value);
    })
    
    p2.then(function(value){
      console.log(value);
    })

    // logs `"p2"`, `"p1"`
    var p1 = Promise.resolve("p1")
    
    var p2 = Promise.resolve(Promise.resolve("p2")); 
    
    p2.then(function(value){
      console.log(value);
    })
    
    p1.then(function(value){
      console.log(value);
    })

    【讨论】:

    • 当然,但我猜 OP 想知道为什么?
    • @JaromandaX 为什么具体是什么?为什么按照OP调用代码的顺序调用代码?
    • 为什么不同的模式会产生不同的顺序
    • 是的...但是为什么var p2 = new Promise(function(resolve, reject){ resolve(Promise.resolve("p2")); })var p2 = Promise.resolve(new Promise(function(resolve, reject){ resolve("p2") })) 不同 - 我希望所有 3 都输出 p2 然后 p1(就像它在节点中一样)
    • @PageYe 不同之处在于在p2 Promise 构造函数中调用Promise.resolve()。当代码为var p2 = new Promise(function(resolve, reject){ resolve("p2"); }) 时,"p2" 首先记录在console。建议在 bugs.chromium.org/p/monorail/issues/list 提交问题,向 Chromium 浏览器中 Promise 的实现者询问具体细节和他们对 Promise 实现的解释
    猜你喜欢
    • 2019-06-20
    • 2016-03-05
    • 2017-05-17
    • 2019-12-16
    • 2019-08-31
    • 2018-11-16
    相关资源
    最近更新 更多