上文中主要说了一下 Promise 的简单运行,实现了 then 方法的调用以及多个 then 方法的处理,但是还没有做到如何在使用 then 的形式链式调用,也没有做错误处理,接来下本文就加上错误处理以及没有做的链式调用和 all 方法实现
废话不多数,接上文。

实现 then 方法的链式调用

首先如果要实现链式调用的话,就需要返回一个 Promise 对象,就像 JQ 那样链式的一样。思考一下,在 then 里面 return 一个返回值作为下一个 then 方法的参数。

then(resolve, reject) {
  const p = new MyPromise((nextResolve, nextReject) => {
    // 只有完成的状态才能使用 then
    if (this.status === FULFILLED) {
      // 获取到上一个promise成功回调执行的结果
      const result = resolve(this.value)
      resolvePromise(result, nextResolve, nextReject)
    } else if (this.status === REJECTED) {
      const result = reject(this.error)
      resolvePromise(result, nextResolve, nextReject)
    } else if (this.status === PENDING) {
      // 这里要保存函数
      this.onResolveCallbacks.push(() => {
        const result = resolve(this.value);
        resolvePromise(result, nextResolve, nextReject)
      })
      this.onRejectCallbacks.push(() => {
        const result = reject(this.error)
          resolvePromise(result, nextResolve, nextReject)
      })
    }
  })
  
  return p
}

// 统一处理
function resolvePromise(result, nextResolve, nextReject) {
  // 判断执行的结果是否是一个promise对象
  if (result instanceof MyPromise) {
    result.then(nextResolve, nextReject);
  } else {
    // 将上一个promise成功回调执行的结果传递给下一个promise成功的回调
    nextResolve(result);
  }
}

实现一下 all 方法

all 方法的特点就是传入一个数组且数组内的元素都是一个个 Promise 对象,如果成功就按数字顺序打印出来,其中一个失败则直接返回错误。

这里要注意下 按顺序执行打印,如果使用原生 JavaScript 要怎么去实现这个方法呢?思考一下?

all(arr) {
  return new MyPromise((resolve, reject) => {
    let list = []
    let count = 0
    // for 循环去执行 promise
    for (let i = 0; i < arr.length; i++) {
      arr[i].then((value) =>{
        // 把执行的结果保存到新的数组中
        list.push(value)
        // 保存之后再让 count + 1
        count++
        // 当 count 的数量刚好和 arr 的数量相等时,通过 resolve 返回新的数组
        if (count === arr.length) {
          resolve(list)
        }
      },(error) => {
        // 其中一个有错误就 reject 出来
        reject(error)
      })
    }
  })
}

像这样 all 的方法就实现了。

总结

如果认真的通篇看下来,实现 Promise 其实不算难的,难就难在整体的思路以及各方法直接调用的处理,顶多来说就是不停的设置回调,最复杂的地方也就是链式处理,说白了就是 return 出的 MyPromise 然后在调用将上一个 Promise 成功回调执行的结果传递给下一个 Promise 成功的回调,如此便实现了传递效果。

本文参考以下下文章:
从一道让我失眠的 Promise 面试题开始,深入分析 Promise 实现细节