Skip to content

Promise ​

2023-05-17 15:56:41

更优雅的来表示异步回调,解决回调地狱问题。

Promise 的状态 ​

Promise 有三个状态

  • pending 等待
  • fulfilled 成功
  • rejected 失败

并且当 Promise 的状态从 pending 改变为 fulfilled 或 rejected 后不会再改变

Promise 的方法 ​

resolve ​

resolve 方法将一个普通值转换为 promise 类型的数据。

第一种,使用 resolve 方法传递一个非 promise 类型的数据,将结果转换为成功的 promise 对象。

ts
const p1 = Promise.resolve('123')

console.log(p1)

第二种,使用 resolve 方法传递一个 promise 类型的数据,作为参数的 promise 的状态和结果将决定 resolve 方法返回结果的状态和结果。

ts
const p1 = Promise.resolve(
  new Promise((resolve, reject) => {
    reject('p1')
  })
)

console.log(p1)

reject ​

reject 方法将始终返回一个失败的 promise 对象,无论参数是什么,最终都将返回失败的 promise。

ts
const p1 = Promise.reject(
  new Promise((resolve, reject) => {
    resolve('p1')
  })
)

console.log(p1)

all ​

只有所有的 promise 状态都为 fulfilled,才会返回 fulfilled,只要有一个失败了就会返回 rejected。

ts
const p1 = new Promise((resolve, reject) => {
  resolve('p1')
})
const p2 = new Promise((resolve, reject) => {
  resolve('p2')
})
const p3 = new Promise((resolve, reject) => {
  reject('p3')
})

const result = Promise.any([p1, p2, p3])
console.log(result);

allSettle ​

allSettle 方法和 all 方法类似,当所有的 promise 方法都有结果了才会执行,无论这些 promise 的结果为成功还是失败。

主要用来确定一些异步操作是否全部执行结束了。

any ​

和 all 方法相反,any 方法只要有一个 promise 状态为 fulfilled,返回结果就为 fulfilled。

只有所有的 promise 全都 rejected 结果才会返回 rejected。

ts
const p1 = new Promise((resolve, reject) => {
  reject('p1')
})
const p2 = new Promise((resolve, reject) => {
  resolve('p2')
})
const p3 = new Promise((resolve, reject) => {
  reject('p3')
})

const result = Promise.any([p1, p2, p3])
console.log(result);

比如此处这个案例,传入了三个 promise 实例,p1 失败,p2 成功,p3 失败,所以输出的结果为 p2.

再看下面这个案例,我们做一个延时。前面两秒都为 rejected,在第三秒的时候 p3 执行,那么最后也会返回 fulfilled。

ts
const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('p1')
  }, 1000);
})
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('p2')
  }, 2000);
})
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('p3')
  }, 3000);
})

const result = Promise.any([p1, p2, p3])
console.log(result);

race ​

race 是赛跑的意思,也就是说,只要有一个实例最先返回了状态,那么 race 方法就会返回此结果。

我们看下面这个 🌰,虽然传递顺序为 p3,p2,p1,但是 p1 最先执行,所以返回的结果为 rejected。

ts
const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('p1')
  }, 1000);
})
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('p2')
  }, 2000);
})
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('p3')
  }, 3000);
})

const result = Promise.any([p3, p2, p1])
console.log(result);

finally ​

ES9 新增的方法,表示一个 promise 对象最终无论变成 fulfilled 还是 rejected 状态,最后都会执行 finally 方法,

finally 方法的回调函数没有参数

ts
const p1 = new Promise((resolve, reject) => {
  resolve('p1')
})

p1.then(res => {
  console.log(res)
})
  .catch(err => {
    console.log(res)
  })
  .finally(() => {
    console.log('执行结束')
  })

console.log(p1)

手写 promise ​

ts
class MyPromise {
  constructor(executor) {
    // 初始化状态
    this.PromiseState = 'pending'
    // 初始化结果
    this.PromiseResult = undefined

    // 使用箭头函数 因为箭头函数没有自己的this
    const resolve = value => {
      // 状态只能修改一次
      if (this.PromiseState !== 'pending') return
      this.PromiseState = 'fulfilled'
      this.PromiseResult = value
    }
    const reject = value => {
      if (this.PromiseState !== 'pending') return
      this.PromiseState = 'rejected'
      this.PromiseResult = value
    }

    const then = () => {}

    try {
      //调用执行器函数
      executor(resolve, reject)
    } catch (err) {
      reject(err)
    }
  }
}

Released under the MIT License.