自己封装一个Promise详解,手撕Promise

六、手撕(自定义)Promise

Promise是JS异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步编程解决方案之一,本文详细介绍了如何手写一个Promise,即手撕Promise,主要封装了Promise的then、catch、resolve、reject、all、race方法

1. 初始化结构搭建

/*
自定义 Promise
*/
/*
Promise 构造函数
excutor: 内部同步执行的函数 (resolve, reject) => {}
*/
function Promise(executor) {

}

/* then方法
为 promise 指定成功/失败的回调函数
函数的返回值是一个新的 promise 对象
*/
Promise.prototype.then = function (onResolved, onRejected) {

}
/*
为 promise 指定失败的回调函数
是 then(undefined, onRejected)的语法糖
*/
Promise.prototype.catch = function (onRejected) {
}
/*
返回一个指定了成功 value 的 promise 对象
*/
Promise.resolve = function (value) {
}
/*
返回一个指定了失败 reason 的 promise 对象
*/
Promise.reject = function (reason) {
}
/*
返回一个 promise, 只有 promises 中所有 promise 都成功时, 才最终成功, 只要有一个失败就直接失败
*/
Promise.all = function (promises) {
}
/*
返回一个 promise, 一旦某个 promise 解决或拒绝, 返回的 promise 就会解决或拒绝。
*/
Promise.race = function (promises) {
}

2. Promise 构造函数的实现

function Promise(executor) {
  // 添加属性
  this.PromiseState = 'pending'
  this.PromiseResult = null
  // 声明属性
  this.callbacks = []
  // 保存实例对象的this
  const self = this

  /*
    异步处理成功后应该调用的函数
    value: 将交给 onResolve()的成功数据
  */
  function resolve(data) {
    // 判断状态 保证状态只更改一次
    if (self.PromiseState !== 'pending') return
    // 1.修改对象的状态(PromiseState)
    self.PromiseState = 'fulfilled'
    // 2.设置对象结果值(PromiseResult)
    self.PromiseResult = data
    // 异步调用成功的回调
    setTimeout(() => {
      self.callbacks.forEach(i => i.onResolved(data))
    });
  }

  /*
    异步处理失败后应该调用的函数
    reason: 将交给 onRejected()的失败数据
  */
  function reject(data) {
    if (self.PromiseState !== 'pending') return
    // 1.修改对象的状态(PromiseState)
    self.PromiseState = 'rejected'
    // 2.设置对象结果值(PromiseResult)
    self.PromiseResult = data
    // 异步调用失败的回调
    setTimeout(() => {
      self.callbacks.forEach(i => i.onRejected(data))
    });
  }

  // 抛出错误改变状态
  try {
    // 同步调用【执行器函数】
    executor(resolve, reject)
  } catch (error) {
    reject(error)
  }
}

2. promise.then()的实现

/* then方法
    为 promise 指定成功/失败的回调函数
    函数的返回值是一个新的 promise 对象
*/
Promise.prototype.then = function (onResolved, onRejected) {
  const self = this
  // 判断回调函数
  // 如果 onResolved/onRejected 不是函数, 可它指定一个默认的函数
  if (typeof onRejected !== 'function') {
    onRejected = (reason) => {
      throw reason
    }
  }
  if (typeof onResolved !== 'function') {
    onResolved = value => value
  }

  return new Promise((resolve, reject) => {
    /*
      专门抽取的用来处理 promise 成功/失败结果的函数
      callback: 成功/失败的回调函数
    */
    function callback(onEvent) {
      try {
        let result = onEvent(self.PromiseResult)
        // 判断
        if (result instanceof Promise) {
          // 如果返回结果是Promise类型的对象,PromiseState和PromiseResult由改对象决定
          result.then(v => {
            resolve(v)
          }, r => {
            reject(r)
          })
        } else {
          // 返回的结果为非Promise对象,返回PromiseState为fufilled的Promise对象
          // 结果的状态为成功
          resolve(result)
        }
      } catch (error) {
        reject(error)
      }
    }

    // 调用成功回调函数
    if (this.PromiseState === 'fulfilled') {
      setTimeout(() => {
        callback(onResolved)
      });

    }
    // 调用失败回调
    if (this.PromiseState === 'rejected') {
      setTimeout(() => {
        callback(onRejected)
      });

    }
    // 异步
    if (this.PromiseState === 'pending') {
      // 保存异步执行的回调函数
      this.callbacks.push({
        onResolved: function () {
          callback(onResolved)
        },
        onRejected: function () {
          callback(onRejected)
        }
      })
    }
  })
}

3. promise.catch()的实现

// 添加catch方法 返回Promise对象
Promise.prototype.catch = function (onRejected) {
  return this.then(undefined, onRejected)
}

4. Promise.resolve()的实现

// 添加resolve方法
Promise.resolve = function (data) {
  return new Promise((resolve, reject) => {
    try {
      // 判断
      if (data instanceof Promise) {
        // 如果返回结果是Promise类型的对象,PromiseState和PromiseResult和该对象一致
        data.then(v => {
          resolve(v)
        }, r => {
          reject(r)
        })
      } else {
        // 返回的结果为非Promise对象,返回PromiseState为fufilled的Promise对象
        // 结果的状态为成功
        resolve(data)
      }
    } catch (error) {
      reject(error)
    }
  })
}

5. Promise.reject()的实现

// 添加reject方法
Promise.reject = function (data) {
  return new Promise((resolve, reject) => {
    reject(data)
  })
}

6. Promise.all()的实现

// 添加all方法
// 返回一个新的 promise
// 只有所有的 promise 都成功才成功, 只要有一个失败了就直接失败
// 如果都成功,返回的结果PromiseResult是三个成功结果形成的数组
// 如果存在失败,直接失败,就返回的结果PromiseResult是第一个失败结果
Promise.all = function (promiseArr) {
  return new Promise((resolve, reject) => {
    let result = []
    let count = 0
    for (let i = 0; i < promiseArr.length; i++) {
      promiseArr[i].then(
        v => {
          // 按Promise对象数组的顺序放置对应结果
          result[i] = v
          count++
          // 当全部成功时,返回的Promise对象成功,结果为成功数组
          if (count === promiseArr.length) {
            resolve(result)
          }
        },
        r => {
          // 当有一个失败,则返回该失败的Promise对象
          reject(r)
        }
      )
    }
  })
}

7. Promise.race()的实现

// 添加race方法
// 返回一个新的 promise, {{第一个完成的}} promise 的结果状态就是最终的结果状态
Promise.race = function (promiseArr) {
  return new Promise((resolve, reject) => {
    for (let i = 0; i < promiseArr.length; i++) {
      promiseArr[i].then(
        v => {
          resolve(v)
        },
        r => {
          reject(r)
        })
    }
  })
}

8. ES6的class实现Promise

class Promise {
  // 构造方法
  constructor(executor) {
    // 添加属性
    this.PromiseState = 'pending'
    this.PromiseResult = null
    // 声明属性
    this.callbacks = []
    // 保存实例对象的this
    const self = this

    function resolve(data) {
      // 判断状态 保证状态只更改一次
      if (self.PromiseState !== 'pending') return
      // 1.修改对象的状态(PromiseState)
      self.PromiseState = 'fulfilled'
      // 2.设置对象结果值(PromiseResult)
      self.PromiseResult = data
      // 异步调用成功的回调
      setTimeout(() => {
        self.callbacks.forEach(i => i.onResolved(data))
      });
    }

    function reject(data) {
      if (self.PromiseState !== 'pending') return

      // 1.修改对象的状态(PromiseState)
      self.PromiseState = 'rejected'
      // 2.设置对象结果值(PromiseResult)
      self.PromiseResult = data
      // 异步调用失败的回调
      setTimeout(() => {
        self.callbacks.forEach(i => i.onRejected(data))
      });


    }

    try {
      // 同步调用【执行器函数】
      executor(resolve, reject)
    } catch (error) {
      reject(error)
    }

  }

  // then方法
  then(onResolved, onRejected) {
    const self = this
    // 判断回调函数
    if (typeof onRejected !== 'function') {
      onRejected = (reason) => {
        throw reason
      }
    }
    if (typeof onResolved !== 'function') {
      onResolved = value => value
    }

    return new Promise((resolve, reject) => {
      // 封装函数
      function callback(onEvent) {
        try {
          let result = onEvent(self.PromiseResult)
          // 判断
          if (result instanceof Promise) {
            // 如果返回结果是Promise类型的对象,PromiseState和PromiseResult由改对象决定
            result.then(v => {
              resolve(v)
            }, r => {
              reject(r)
            })
          } else {
            // 返回的结果为非Promise对象,返回PromiseState为fufilled的Promise对象
            // 结果的状态为成功
            resolve(result)
          }
        } catch (error) {
          reject(error)
        }
      }


      // 调用回调函数
      if (this.PromiseState === 'fulfilled') {
        setTimeout(() => {
          callback(onResolved)
        });

      }
      if (this.PromiseState === 'rejected') {
        setTimeout(() => {
          callback(onRejected)
        });

      }
      // 异步
      if (this.PromiseState === 'pending') {
        // 保存回调函数
        this.callbacks.push({
          onResolved: function () {
            callback(onResolved)
          },
          onRejected: function () {
            callback(onRejected)
          }
        })
      }
    })

  }

  // catch方法
  catch (onRejected) {
    return this.then(undefined, onRejected)
  }

  // resolve方法
  static resolve(data) {
    return new Promise((resolve, reject) => {
      try {
        // 判断
        if (data instanceof Promise) {
          // 如果返回结果是Promise类型的对象,PromiseState和PromiseResult由改对象决定
          data.then(v => {
            resolve(v)
          }, r => {
            reject(r)
          })
        } else {
          // 返回的结果为非Promise对象,返回PromiseState为fufilled的Promise对象
          // 结果的状态为成功
          resolve(data)
        }
      } catch (error) {
        reject(error)
      }
    })
  }

  // reject方法
  static reject(data) {
    return new Promise((resolve, reject) => {
      reject(data)
    })
  }

  // 添加all方法
  // 返回一个新的 promise
  // 只有所有的 promise 都成功才成功, 只要有一个失败了就直接失败
  // 如果都成功,返回的结果PromiseResult是三个成功结果形成的数组
  // 如果存在失败,直接失败,就返回的结果PromiseResult是第一个失败结果
  static all(promiseArr) {
    return new Promise((resolve, reject) => {
      let result = []
      let count = 0
      for (let i = 0; i < promiseArr.length; i++) {
        promiseArr[i].then(
          v => {
            result[i] = v
            count++
            if (count === promiseArr.length) {
              resolve(result)
            }
          },
          r => {
            reject(r)
          }
        )
      }
    })
  }

  // race方法
  // 返回一个新的 promise, {{第一个完成的}} promise 的结果状态就是最终的结果状态
  static race(promiseArr) {
    return new Promise((resolve, reject) => {
      for (let i = 0; i < promiseArr.length; i++) {
        promiseArr[i].then(
          v => {
            resolve(v)
          },
          r => {
            reject(r)
          })
      }
    })
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嘎嘎油

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值