zires 博客

[QA] - javascript中的promise

April 25, 2018

Q: 如何构建一个promise对象?

var p = new Promise(function(resolve, reject){
  // resolve() or reject()
})

Q: 传入new Promise中的回调函数是同步调用还是异步调用?

同步调用,立即执行。

Q: resolve表示成功,reject表示失败吗?

严格上讲,reject表示拒绝,而resolve可能是成功执行,也可能是拒绝,要根据传入的参数而定。

传入resolve的参数如果是立即值,则用这个值完成;如果是一个promise对象或者thenable对象,则递归展开取最终状态。

Q: Promise.resolve(..)表示什么?

创建promise对象的另一种快捷方式,根据传入的参数不同,会有所区别:

Promise.resolve(objectOrPrimitives)

var onFulfilled = function(fulfilled) {
  console.log(fulfilled + ' fulfilled')
}

var p1 = Promise.resolve('foo')
// 等价于
var p2 = new Promise(function(resolve){
  resolve('foo')
})

p1.then(onFulfilled) // "foo fulfilled"

p2.then(onFulfilled) // "foo fulfilled"

Promise.resolve(thenable)

var thenable = {
  then: function(cb) { cb('thenable foo'); }
}

var nestThenable = {
  then: function(cb) {
    cb({
      then: function(cb) { cb('nest thenable'); }
    })
  }
}

var promise = Promise.resolve(thenable)

var nestThenablePromise = Promise.resolve(nestThenable)

promise.then(onFulfilled) // "thenable foo fulfilled"

// 递归展开
nestThenablePromise.then(onFulfilled) // "nest thenable fulfilled"

Promise.resolve(promise)

var promise = new Promise(function(resolve) {
  resolve(nestThenable)
})

// 同一个promise
console.log(promise === Promise.resolve(promise)) // true

Promise.resolve(),也可以不带任何参数,返回一个resolved状态的promise。

一点小小的区别:

setTimeout(fn, 0) // 下一轮事件循环开始时执行

Promise.resolve().then(fn) // 本轮事件循环结束时执行

Q: Promise.resolve(..)与new Promise回调函数中的resolve行为一致吗?

一致

Q: 如果Promise.reject(..)传入一个thenable对象,结果有可能是成功完成状态吗?

不可能。永远返回一个状态为rejected的promise。如果是传入一个thenable对象,那么这个对象会作为reject的理由,原封不动的传给后续的调用。

Q: promise的状态变化是怎样的?

  • pending 初始化状态,待定。既不是fulfilled也不是rejected
  • fulfilled 已执行。
  • rejected 已拒绝。
  • settled 已解决。fulfilled或者rejected

Q: promise一旦决议,决议值还可以更改吗?

不能。

Q: 存在一个pending状态的promise吗?

当然存在。

Q: Promise是用来解决什么问题?

Promise是异步编程的一种解决方案。

Q: 相比异步回调,Promise的优势在哪里?

  • Promise允许我们以同步的方式组织异步代码
  • 特别的,当在回调中再嵌套异步的时候,Promise避免导致回调地狱
  • Promise的错误处理比回调更合理
  • Promise一旦决议,只有一种状态,并且永远不会改变,这样就避免了回调过早,过晚,过多,过少的问题
  • Promise可以链式调用

Zires

Hi~,i am zires, an IT engineer, live in Shanghai. You can get in touch with me via Github stackoverflow