【问题标题】:What's the difference between resolve(thenable) and resolve('non-thenable-object')?resolve(thenable) 和 resolve('non-thenable-object') 有什么区别?
【发布时间】:2019-05-22 11:20:02
【问题描述】:

我试图了解resolve(thenable)resolve('non-thenable-object') 之间的区别。

在下面的示例中,使用 promise 而不是 thenable,因为 promise 也是 thenable,可能更容易理解。

演示1:resolve(promise)

let resolvePromise = new Promise(resolve => {
  let resolvedPromise = Promise.resolve()
  resolve(resolvedPromise)
})
resolvePromise.then(() => {
  console.log('resolvePromise resolved')
})
let resolvedPromiseThen = Promise.resolve().then(res => {
  console.log('promise1')
})
resolvedPromiseThen
  .then(() => {
    console.log('promise2')
  })
  .then(() => {
    console.log('promise3')
  })

结果:

  • 承诺1
  • promise2
  • resolvePromise 已解决
  • 承诺3

演示2:resolve('non-thenable-object')

let resolvePromise = new Promise(resolve => {
  resolve('non-thenable-object')
})
resolvePromise.then(() => {
  console.log('resolvePromise resolved')
})
let resolvedPromiseThen = Promise.resolve().then(res => {
  console.log('promise1')
})
resolvedPromiseThen
  .then(() => {
    console.log('promise2')
  })
  .then(() => {
    console.log('promise3')
  })

结果:

  • resolvePromise 已解决
  • 承诺1
  • promise2
  • 承诺3

所以,我检查了规范并找到了Promise Resolve Functions .然后到PromiseResolveThenableJobEnqueueJob

所以,根据规范,我认为 demo1 就像

演示3:

let resolvePromise = new Promise(resolve => {
  let resolvedPromise = Promise.resolve()
 // resolve(resolvedPromise)
  // works like 
  Promise.resolve().then(() => {
    Promise.resolve(resolvedPromise).then(() => {
      resolve()
   })
  })
})
resolvePromise.then(() => {
  console.log('resolvePromise resolved')
})
let resolvedPromiseThen = Promise.resolve().then(res => {
  console.log('promise1')
})
resolvedPromiseThen
  .then(() => {
    console.log('promise2')
  })
  .then(() => {
    console.log('promise3')
  })

我这么认为是因为Promise Resolve Functions 说:

  1. 执行 EnqueueJob("PromiseJobs", PromiseResolveThenableJob, « promise, resolution, thenAction »)。

PromiseResolveThenableJob 说:

这个 Job 使用提供的 thenable 和它的 then 方法来解决给定的 promise。 此过程必须作为作业进行,以确保在对任何周围代码的评估完成后对 then 方法进行评估。

另外,我认为 demo2

演示4:

//let resolvePromise = new Promise(resolve => {
  //resolve('str')
//})
//works like
let resolvePromise = Promise.resolve('str')

resolvePromise.then(() => {
  console.log('resolvePromise resolved')
})
let resolvedPromiseThen = Promise.resolve().then(res => {
  console.log('promise1')
})

resolvedPromiseThen
  .then(() => {
    console.log('promise2')
  })
  .then(() => {
    console.log('promise3')
  })

正如Promise Resolve Functions 所说:

如果 IsCallable(thenAction) 为 false,则返回 FulfillPromise(promise, resolution)。

虽然 Demo1-Demo3Demo2-Demo4 之间的结果相等,但我仍然不确定如果我是对的。所以,我是来问的

我的逻辑是否正确?如果不是,你如何解释不同的命令 在resolve(thenable)resolve(non-thenable) 之间?

【问题讨论】:

  • 我一般建议不要依赖不相关的 Promise 之间的回调调用顺序。尽管规范给出了特定的排队语义,但它在实践中永远不相关。如果您需要特定的顺序,因为您的回调相互依赖,请通过将您的 Promise 一个接一个地链接来明确这一点。
  • @Bergi,实际上,在实践中,我总是使用 Promise 链来控制异步顺序。但是我真的很想了解规范和原理。
  • 赞成评论。为了理解而理解规范并没有什么错,即使在实践中依赖它并不好。

标签: javascript node.js promise


【解决方案1】:

是的,你的逻辑看起来是对的。

new Promise(resolve => resolve('non-thenable-object')) 等同于 Promise.resolve('non-thenable-object') 在所有用途中。

但是,在您的 Demo3 中,我建议省略 Promise.resolve(resolvedPromise)。我不确定这是否是故意的,但是当 Promise.resolve 的参数已经是一个承诺时,它确实有一个捷径,然后按原样返回 resolvedPromise。你宁愿写

new Promise((resolve, reject) => {
  let resolvedPromise = Promise.resolve();
  // resolve(resolvedPromise) works like 
  Promise.resolve().then(() => resolvedPromise.then(resolve, reject));
});

【讨论】:

  • github.com/xianshenglu/blog/issues/60#issuecomment-449739628 你能解释一下resolveThenable 的例子吗?感觉就像在 resolve(thenable) 和 resolve(promise) 之间以不同的方式工作
  • 不,thenables 和 promises 被resolve 视为完全相同(即作为thenables)。出乎意料的是什么?请注意,您的“thenable”同步调用“onfulfilled”回调(不像真正的承诺那样异步),因此可能会影响排序。
【解决方案2】:

在阅读规范并多次测试后,我认为我可能会得到它。

在我们开始之前,我们必须解决一些问题。

当在Promise executor 中使用resolve 时,我们称它为RESOLVE()。例如,RESOLVE(thenable) 表示如下代码:

  new Promise((resolve,reject)=>{
    resolve(thenable)
  })

resolve(thenable) 表示Promise.resolve(thenable)

好的,让我们开始吧。

Promise.resolve('non-thenable')RESOLVE('non-thenable')

当我们使用Promise.resolve('non-thenable') 时,它涉及到Promise.resolve

那就来PromiseResolve

这就是Promise.resolve('non-thenable') 被转换为的地方

new Promise(resolve=>{
  resolve('non-thenable')
})

所以,我们有结论:

Promise.resolve('non-thenable')可以转换成RESOLVE('non-thenable')


RESOLVE(thenable)

演示1

let resolveThenable = new Promise((resolve, reject) => {
  let thenable = {
    then: function (resolve, reject) {
      console.log('in thenable')
      resolve(42)
    }
  }
  resolve(thenable)
  // works like
  // Promise.resolve().then(() => {
  //   thenable.then(resolve)
  // })
  // should be ?
  // Promise.resolve().then(() => {
  //   thenable.then.[[Value]](resolve)
  // })
  // equivalent to?
  // Promise.resolve().then(() => {
  //   thenable.then(resolve)
  // })
})
resolveThenable.then(() => {
  console.log('resolveThenable resolved')
})
let resolvedPromiseThen = Promise.resolve().then(res => {
  console.log('promise1')
})
resolvedPromiseThen
  .then(() => {
    console.log('promise2')
  })
  .then(() => {
    console.log('promise3')
  })

// 'in thenable'
// 'promise1'
// 'resolveThenable resolved'
// 'promise2'
// 'promise3'

根据Promise Resolve Functions,当我们使用RESOLVE(thenable)时,就到了

然后是PromiseResolveThenableJob

这将使RESOLVE(thenable)

  Promise.resolve().then(() => {
    thenable.then.[[Value]](resolve)
  })

所以,我认为它相当于

  Promise.resolve().then(() => {
    thenable.then(resolve)
  })

得到与RESOLVE(thenable)相同的结果。

所以,我们可以说RESOLVE(thenable) 可以转换为

  Promise.resolve().then(() => {
    thenable.then(resolve)
  })
演示2

let resolvePromise = new Promise((resolve, reject) => {
  let resolvedPromise = Promise.resolve()
  resolve(resolvedPromise)
  // works like
  // Promise.resolve().then(() => {
  //   resolvedPromise.then(() => {
  //     resolve()
  //   })
  // })
  // should be?
  // Promise.resolve().then(() => {
  //   resolvedPromise.then.[[Value]](resolve,reject)
  // })
  // equivalent to ?
  // Promise.resolve().then(() => {
  //   resolvedPromise.then(resolve)
  // })
  // equivalent to ?
  // Promise.resolve().then(() => {
  //   resolvedPromise.then(() => {
  //     resolve()
  //   })
  // })
})
resolvePromise.then(() => {
  console.log('resolvePromise resolved')
})
let resolvedPromiseThen = Promise.resolve().then(res => {
  console.log('promise1')
})
resolvedPromiseThen
  .then(() => {
    console.log('promise2')
  })
  .then(() => {
    console.log('promise3')
  })

// 'promise1'
// 'promise2'
// 'resolvePromise resolved'
// 'promise3'

当我们谈到RESOLVE(resolvedPromise) 时,我们可以发现规范没有区分thenablepromise。所以,同理​​,RESOLVE(resolvedPromise) 可以转化为

  Promise.resolve().then(() => {
    resolvedPromise.then(resolve)
  })

不过,在这种情况下,RESOLVE(thenable)RESOLVE(promise) 之间的顺序是不同的。因为thenable.then 是同步操作,而resolvedPromise.then 是异步操作。它们不是同一个then 方法。

所以,这是我们的结论:

RESOLVE(thenable)RESOLVE(promise) 都可以转换为

 new Promise((resolve, reject) => {
      Promise.resolve().then(() => {
        thenable.then(resolve)
      })
 })

Promise.resolve(thenable)

使用Promise.resolve(promise) 非常简单,因为它返回promise 参数。

然而,当使用Promise.resolve(thenable) 时事情变得复杂了,而thenable 并不是一个承诺。我们称之为Promise.resolve(nonPromiseThenable)

根据Promise.resolve ( x )

接下来就是

所以,Promise.resolve(nonPromiseThenable) 可以转换为

 new Promise(resolve => { 
   resolve(nonPromiseThenable)
 })

终于来了

 new Promise(resolve => { 
   Promise.resolve().then(() => { 
     nonPromiseThenable.then(resolve) 
   }) 
 })

您可以在下面的演示中进行测试。

var thenable = {
  then(resolve, reject) {
    resolve(1)
  }
}
// code transformation 
Promise.resolve(thenable).then(res => {
  console.log(res)
})
// equal 
// new Promise(resolve => { 
//   resolve(thenable) 
// }).then(res => { 
//   console.log(res) 
// }) 
// equal 
// new Promise(resolve => { 
//   Promise.resolve().then(() => { 
//     thenable.then(resolve) 
//   }) 
// }).then(res => { 
//   console.log(res) 
// }) 

new Promise(resolve => resolve(2))
  .then(res => {
    console.log(res)
  })
  .then(res => console.log(3))

最后我们做个总结:

  • Promise.resolve('nonThenable') 可以转换为 RESOLVE('nonThenable')。它们具有相同的效果。
  • Promise.resolve(thenable)RESOLVE(thenable) 不同。它们有不同的效果。
  • RESOLVE(thenable)RESOLVE(promise) 可以转换为 new Promise((resolve, reject) => { Promise.resolve().then(() => { thenable.then(resolve) }) })
  • Promise.resolve(promise) === promisePromise.resolve(nonPromiseThenable) 可以转换为 new Promise(resolve => { Promise.resolve().then(() => { nonPromiseThenable.then(resolve) }) })

【讨论】:

    猜你喜欢
    • 2017-07-10
    • 2019-01-20
    • 1970-01-01
    • 2011-11-30
    • 2021-05-04
    • 2015-06-08
    • 1970-01-01
    • 2017-05-17
    • 2019-12-16
    相关资源
    最近更新 更多