手写 promise 函数

47 阅读1分钟

promise 在异步处理过程中很常用,先看一下基本使用,方便接下来我们进行手写。

1. promise 基本用法

let p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    if (Math.random()>0.6) {
      resolve('resolve')
      return
    }
    reject('reject')
  }, 1000)
})

p1.then(res => {
  console.log(res)
}).catch(err => {
  console.log(err)
})

2. 定义Promise 类

class MyPromise {

  constructor(executor) {
    //  记录初始化 promise 状态
    this.state = 'pending'
    //  thenList 状态变为 fulfilled 时需要执行的函数列表
    this.thenList = []
    //  catchList 状态变为 rejected 时需要执行的函数列表
    this.catchList = []
    executor(this.resolve.bind(this), this.reject.bind(this))
  }

  resolve(val) {
    this.state = 'fulfilled'
    //  取出 thenList 中第一个函数并执行
    let rv = this.thenList.shift()(val)
    //  如果 thenList 中还有函数则把上一个执行的返回值传给下一个
    while (this.thenList.length>0) {
      this.resolve(rv)
    }
  }

  reject(msg) {
    this.state = 'rejected'
    //  取出 catchList 中第一个函数并执行
    let rv = this.catchList.shift()(msg)
    //  如果 catchList 中还有函数则把上一个执行的返回值传给下一个
    while (this.catchList.length>0) {
      this.resolve(rv)
    }
  }

  then(success, fail = () => {}) {
    this.thenList.push(success)
    this.catchList.push(fail)
    return this
  }
}

3. 测试

// 在异步任务结束前,调用then函数
p.then(function(data){
  console.log(4, data)
  return data
},function(err){
  console.log(4, err)
}).then(function(data){
  return data
})
// 在异步任务结束后, 调用then函数
p.then(function(data){
  console.log(5, data)
},function(err){
  console.log(5, err)
})