Promise


# Promise

# 基本语法

创建 Promise 实例:

const promise = new Promise(function(resolve, reject) {
  // ... some code

  if ( /* 异步操作成功 */ ) {
    resolve(value)
  } else {
    reject(error)
  }
})
1
2
3
4
5
6
7
8
9

Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolvereject,它们是两个函数,由 JavaScript 引擎提供,不用自己部署。

  • 处理结果正常的话,调用 resolve(处理结果值),将 Promise 对象的状态从「未完成」变为「成功」(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去。
  • 处理结果错误的话,调用 reject(Error 对象),将 Promise 对象的状态从「未完成」变为「失败」(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

Promise 实例生成以后,可以用 then 方法分别指定 resolved 状态和 rejected 状态的回调函数:

promise.then(function(value) {
  // success
}, function(error) {
  // failure
})
1
2
3
4
5

Promise 内部的状态(pending、fulfilled、rejected)走向如下图所示:

state: 'pending'new Promiseresolve(res)reject(err)state: 'fulfilled'result: resstate: 'rejected'result: err成功失败

(Promise 状态的走向)

# Promise.prototype.then()

基本语法

promise.then(onFulfilled, onRejected)

示例

var promise = new Promise(function(resolve, reject) {
  resolve('传递给then的值')
})
promise.then(function(value) {
  console.log(value)
}, function(error) {
  console.error(error)
})
1
2
3
4
5
6
7
8

这段代码创建一个 Promise 对象,定义了处理 onFulfilled 和 onRejected 的函数(handler),然后返回这个 Promise 对象。

这个 Promise 对象会在变为 resolve 或者 reject 的时候分别调用相应注册的回调函数。

  • 当 handler 返回一个正常值的时候,这个值会传递给 Promise 对象的 onFulfilled 方法。
  • 定义的 handler 中产生异常的时候,这个值则会传递给 Promise 对象的 onRejected 方法。

# Promise.prototype.catch()

可以使用 Promise 对象的 catch 方法来捕获异步操作过程中出现的任何异常。

基本语法

p.catch(onRejected)

p.catch(function(reason) { // rejection })

示例

function test() {
  return new Promise((resolve, reject) => {
    reject(new Error('es'))
  })
}

test().catch((e) => {
  console.log(e.message) // es
})
1
2
3
4
5
6
7
8
9

注意

虽然都能被 catch 捕获到,但不建议在 Promise 内部使用 throw new Error() 来触发异常,而应该使用 reject(new Error()) 的方式来做,因为 throw 的方式并没有改变 Promise 的状态。

# Promise.resolve()

静态方法 Promise.resolve(value) 可以认为是 new Promise() 方法的快捷方式。

比如下面两个写法是等价的:

// 写法一
Promise.resolve(42)

// 写法二
new Promise(function(resolve) {
  resolve(42)
})
1
2
3
4
5
6
7

上面代码中的 resolve(42) 会让这个 Promise 对象立即进入确定(即 resolved)状态,并将 42 传递给后面 then 里所指定的 onFulfilled 函数。

方法 Promise.resolve(value) 的返回值也是一个 Promise 对象,所以我们可以像下面那样接着对其返回值进行 .then 调用:

Promise.resolve(42).then(function(value) {
  console.log(value)
})
1
2
3

这种简写方式在进行 Promise 对象的初始化或者编写测试代码的时候都非常方便。

# Promise.reject()

Promise.reject(error) 是和 Promise.resolve(value) 类似的静态方法,是 new Promise() 方法的快捷方式。

下面两个写法是等价的:

// 写法一
Promise.reject(new Error("出错了"))

// 写法二
new Promise(function(resolve, reject) {
  reject(new Error('出错了'))
})
1
2
3
4
5
6
7

这段代码的功能是调用该 Promise 对象通过 .then 指定的 onRejected 函数,并将错误(Error)对象传递给这个 onRejected 函数。

Promise.reject(new Error('BOOM!'))
1

# Promise.all()

基本语法

Promise.all(promiseArray)

示例

var p1 = Promise.resolve(1)
var p2 = Promise.resolve(2)
var p3 = Promise.resolve(3)
Promise.all([p1, p2, p3]).then(function(results) {
  console.log(results) // [1, 2, 3]
})
1
2
3
4
5
6

Promise.all() 生成并返回一个新的 Promise 对象,所以它可以使用 Promise 实例的所有方法。参数传递 promise 数组中所有的 Promise 对象都变为 resolve 的时候,该方法才会返回,新创建的 Promise 则会使用这些 promise 的值。

如果参数中的任何一个 promise 为 reject 的话,则整个 Promise.all 调用会立即终止,并返回一个 reject 的新的 Promise 对象。

由于参数数组中的每个元素都是由 Promise.resolve 包装(wrap)的,所以 Promise.all 可以处理不同类型的 Promise 对象。

# Promise.race()

基本语法

Promise.race(promiseArray)

示例

var p1 = Promise.resolve(1)
var p2 = Promise.resolve(2)
var p3 = Promise.resolve(3)
Promise.race([p1, p2, p3]).then(function(value) {
  console.log(value) // 1
})
1
2
3
4
5
6

Promise.race() 生成并返回一个新的 Promise 对象。

参数 promise 数组中的任何一个 Promise 对象如果变为 resolve 或者 reject 的话,该函数就会返回,并使用这个 Promise 对象的值进行 resolve 或者 reject

# 参考文档

(完)