手写Promise

48 阅读5分钟

Promise

  • 定义语法结构

    1. 定义 Promise

      • 接收一个同步立即执行的执行器函数 executor,此函数接收两个函数作为参数 resolve() 调用此函数 Promise 状态由 pending 改变为 fulfilled reject() 调用此函数 Promise 状态由 pending 改为 rejected

        function Promise(executor) {
        
        // 定义resolve,和reject函数
        resolve = () => {
        
        }
        reject = () => {
        
        }
        executor(resolve, reject)
        }
        
    2. 定义 Promise 的实例方法:then(),catch()

      • then()

        • 指定成功和失败的回调, 接收两个参数 onResolve 和 onRejected,这两个参数是可选的, 方法返回一个新的 Promise,

          Promise.prototype.then = function (onResolve, onRejected) {
          
          }
          
          
      • catch()

        • catch()方法只接收一个参数 onRejected,指定失败的回调, 这个方法就是一个语法糖,调用它相当于调用 Promise.prototype.then(null,onReject)
        Promise.prototype.catch = function (onRejected) {
        
          }
        
    3. 定义静态方法 resolve(),reject(),all()

      • resolve()

        • 实例化一个成功的回调,这个成功的 Promise 的值对应着传给 Promise.resolve()的第一个参数,多余的参数会被忽略, 如果传入的参数本身就是一个 Promise 那么他的行为类似于传入了一个空包装,而且会保留传入 Promise 的状态
        Promise.resolve = function (onResolve) {
        
        }
        
      • reject()

        • 与 Promise.resolve()类似,实例化一个失败的 Promise 并抛出一个异步错误,这个异步错误不会被 try/catch 捕获,只能通过失败处理程序捕获 这个失败的 Promise 的值对应着传给 Promise.reject()的第一个参数,多余的参数会被忽略, 与 Promise.resolve 不同的是如果传入的参数本身就是一个 Promise 那么这个传入的 Promise 就会成为失败 Promise 的理由
        Promise.reject = function (onRejected) {
        
        }
        
      • all()

        • 接收一个可迭代对象作为参数,可迭代对象中的元素会通过 Promise.resolve()转化为 Promise 可迭代对象中所有的 Promise 成功才会返回成功,一个失败则失败,一个 pending 则 pending 若有失败的 Promise 则第一个失败 Promise 的理由就会成为 Promise.all 失败的理由 之后在有失败的 Promise 也不会影响最终 Promise.all 失败的理由,promise.all()会静默处理剩下失败的期约
        Promise.all = function () {
        }
        
        
  • 实现 resolve,reject

    • Promise 有三种状态,且只能更改一次, pending=>resolve , pending=>reject,无论更改为那种状态都是不可逆的

      1. pending 待定(初始状态)
      2. resolve 成功
      3. reject 失败
      // 定义三个状态常量
      const PENDING = 'pending'
      const FULFILLED = 'fulfilled'
      const REJECTED = 'rejected'
      
      function Promise(executor) {
        this.state = PENDING // 初始化状态
        this.result = undefined // 初始化 Promise 返回的结果
      // 定义 resolve,和 reject 函数
      resolve = (value) => {
        if (this.state !== PENDING) return //限制状态只能更新一次
        this.state = FULFILLED // 更新状态为成功
        this.result = value // 更新结果数据
      }
      reject = (reason) => {
        if (this.state !== PENDING) return //限制状态只能更新一次
        this.state = REJECTED // 更新状态为失败
        this.result = reason // 更新结果数据
      }
      executor(resolve, reject)
      }
      
  • 实现 then()方法

      function Promise(executor) {
        this.state = PENDING // 初始化状态
        this.result = undefined // 初始化Promise返回的结果
        this.callbacks = []
        this.callbacks = [] // 保存待执行Promise的数组
      // 定义resolve,和reject函数
        resolve = (value) => {
          if (this.state !== PENDING) return //限制状态只能更新一次
          this.state = FULFILLED // 更新状态为成功
          this.result = value // 更新结果数据
          if (this.callbacks.length > 0) {
            this.callbacks.forEach((item) => {
              item.onResolve(value)
            })
          }
    
        }
        reject = (reason) => {
          if (this.state !== PENDING) return //限制状态只能更新一次
          this.state = REJECTED // 更新状态为失败
          this.result = reason // 更新结果数据
          if (this.callbacks.length > 0) {
            this.callbacks.forEach((item) => {
              item.onRejected(reason)
            })
          }
    
        }
        executor(resolve, reject)
      }
      Promise.prototype.then = function (onResolve, onRejected) {
        // 如果传入的不是一个函数
        if (typeof onResolve !== 'function') onResolve = (value) => value
        if (typeof onRejected !== 'function') onRejected = (reason) => { throw reason }
        const that = this
        return new Promise((resolve, reject) => {
          function handle(callback) {
            const result = callback(that.result)
            /*
              1.如果抛出错误则执行指定失败的回调,error就是失败的Promise结果
              2.如果不是一个Promise则返回成功的回调,成功的value是返回的值
              3.返回一个成功Promise,value为result的value
              4.返回一个失败的Promise,reason 为result 的 reason
            */
            try {
              if (result instanceof Promise) {
                result.then(
                  (value) => resolve(value),
                  (reason) => reject(reason)
                )
              } else {
                resolve(result)
              }
            } catch (error) {
              reject(error)
            }
          }
          // 对当前状态进行判断执行不同的结果
          switch (true) {
            case this.state === FULFILLED:
              // 如果当前是成功的, 异步调用成功的回调, 并根据调用的结果更新返回的promise的状态
              setTimeout(() => {
                // const result = onResolve(this.result)
                // /*
                //   1.如果抛出错误则执行指定失败的回调,error就是失败的Promise结果
                //   2.如果不是一个Promise则返回成功的回调,成功的value是返回的值
                //   3.返回一个成功Promise,value为result的value
                //   4.返回一个失败的Promise,reason 为result 的 reason
                // */
                // try {
                //   if (result instanceof Promise) {
                //     result.then(
                //       (value) => resolve(value),
                //       (reason) => reject(reason)
                //     )
                //   } else {
                //     resolve(result)
                //   }
                // } catch (error) {
                //   reject(error)
                // }
                handle(onResolve)
              },);
              break;
            case this.state === REJECTED:
    
              // 如果当前是失败的, 异步调用失败的回调, 并根据调用的结果更新返回的promise的状态
              setTimeout(() => {
                handle(onRejected)
              },);
              break;
            case this.state === PENDING:
              // 如果pending状态, 保存回调函数,等有结果后执行
              this.callbacks.push({
                onResolve() {
                  handle(onResolve)
                },
                onRejected() {
                  handle(onRejected)
                },
              })
              break;
    
            default:
              break;
          }
        })
      }
    
  • 实现 Promise.reject()

    • 与 Promise.resolve()类似,实例化一个失败的 Promise 并抛出一个异步错误,这个异步错误不会被 try/catch 捕获,只能通过失败处理程序捕获 这个失败的 Promise 的值对应着传给 Promise.reject()的第一个参数,多余的参数会被忽略, 与 Promise.resolve 不同的是如果传入的参数本身就是一个 Promise 那么这个传入的 Promise 就会成为失败 Promise 的理由
      Promise.reject = function (onRejected) {
        return new Promise((resolve, reject) => {
          reject(onResolve)
        })
      }
      
  • 实现 Promise.all()

    • 接收一个可迭代对象作为参数,可迭代对象中的元素会通过 Promise.resolve()转化为 Promise 可迭代对象中所有的 Promise 成功才会返回成功,一个失败则失败,一个 pending 则 pending 若有失败的 Promise 则第一个失败 Promise 的理由就会成为 Promise.all 失败的理由 之后在有失败的 Promise 也不会影响最终 Promise.all 失败的理由,promise.all()会静默处理剩下失败的期约
      Promise.all = function (Promises) {
        // 用于保存已成功的 p 的个数
        let resolvedCount = 0
        // 用于保存已成功的 p 的 value
        const values = []
        return new Promise((resolve, reject) => {
          Promises.forEach((item, index) => {
            if (item.state === REJECTED) {
              reject(item.result)
            }
            Promise.resolve(item).then(
                (value) => {
                // 只有当所有 item 都成功了, 那 all 返回的 promise 才成功, 且成功的结果为所有 it em 的 value 组成的数组
                // 问题 1: 我怎么知道都成功了?
                // 问题 2: 我怎么才得得到所有的 value?
                // values.push(value) // 谁先成功, 谁先保存到数组中 不对
                values[index] = value // value 在数组中的位置与 item 在数组中的位置是对应的
                resolvedCount++
                if (resolvedCount === Promises.length) {
                  resolve(values)
                }
              },
            )
          })
        })
      }