JavaScript 异步编程

143 阅读2分钟

Promise 的生命周期

初始为挂起状态(pending),然后会进入两种状态之一:

1.已完成(fulfilled):promise 的操作已成功结束。

2.已拒绝(rejected):promise 的操作未成功结束,可能是一个错误或是其他原因。

创建 Promise 实例

JavaScript 提供原生的 Promise 构造函数,用来生成 promise 实例(用来解决回调地狱问题)。

const promise = new Promise((resolve, reject) => {
    console.log('Hi, Promise!')
    resolve()
})

promise.then(() => {
    console.log('Hi, then!')
})

console.log('Hi')

输出:
Hi, Promise!
Hi
Hi, then!

Promise 链式调用

const promiseA = () => {
  return new Promise((resolve) => {
    console.log('1')
    resolve()
  })
}

const promiseB = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('2')
      resolve()
    }, 1000)
  })
}

const promiseC = () => {
  return new Promise((resolve) => {
    console.log('3')
    resolve()
  })
}

new Promise((resolve) => {
  resolve()
})
  .then(() => promiseA())
  .then(() => promiseB())
  .then(() => promiseC())

输出:
1
2
3

响应多个 Promise

如果想监视多个 Promise 的状态,从而决定下一个操作,可以使用 Promise.all()Promise.race()

Promise.all() 接受单个可迭代对象(如数组)作为参数,可迭代对象的元素都是 Promise 。该方法会返回一个 Promise ,只有传入所有的 Promise 都已完成,所返回的 Promise 才会完成

const p1 = new Promise((resolve, reject) => {
  resolve(1)
})
const p2 = new Promise((resolve, reject) => {
  resolve(2)
})
const p3 = new Promise((resolve, reject) => {
  resolve(3)
})
const p4 = Promise.all([p1, p2, p3])
p4.catch((res) => {
  console.log(Array.isArray(res))
  console.log(res)
})

输出:
true
[1, 2, 3]
  • 若传递给 Promise.all() 的某个 Promise 被拒绝了,那么方法所返回的 Promise 就会立刻被拒绝,而不必等待其他的 Promise 结束
const p1 = new Promise((resolve, reject) => {
  reject(1)
})
const p2 = new Promise((resolve, reject) => {
  reject(2)
})
const p3 = new Promise((resolve, reject) => {
  resolve(3)
})
const p4 = Promise.all([p1, p2, p3])
p4.catch((res) => {
  console.log(Array.isArray(res))
  console.log(res)
})

输出:
false
1
  • Promise.all()catch 总会接收到单个值,而不是一个数组,是第一个被拒绝的 promise 实例所返回的拒绝值。

Promise.race()Promise.all()不同的地方在于:Promise.race() 在传入的可迭代对象中有一个 Promise 是已决状态时,Promise.race() 所返回的 Promise 立刻变为已决状态

const pa = new Promise((resolve, reject) => {
  resolve(1)
})
const pb = new Promise((resolve, reject) => {
  resolve(2)
})
const pc = new Promise((resolve, reject) => {
  resolve(3)
})
const pd = Promise.race([pa, pb, pc])
pd.then((res) => {
  console.log(Array.isArray(res))
  console.log(res)
})

输出:
1
false

总结:

  • Promise 具有三种状态:挂起、已完成、已拒绝。一个 Promise 起始于挂起态,并在成功时转为完成态,或在失败时转为拒绝态。 then() 方法允许你绑定完成处理函数与拒绝处理函数,而 catch() 方法则只允许你绑定拒绝处理函数
  • 可以将多个 Promise 实例链式调用,.then() 的调用每次都创建并返回新的 Promise 实例,只有当前一个 Promise 决议过之后下一个 Promise 实例才可以被决议。另外,可以使用 Promise.all()Promise.race() 对多个 Promise 实例进行管理。