为何要手写Promise?直接import不行吗?
身处技术圈,前端技术真的是日新月异,异步的实现方式从callback、到Promise、再到Generator、Async/Await,有了长足的发展,Promise作为发展过程中的一种产物其既是callback的一种改良,也是Generator、Async/Await的基础。
直接import一个Promise类库当然可行(在支持的浏览器中直接使用Promise也未尝不可),但是如果我们能够亲手实现一个Promise,那么我们还能够:
- 对Promise的理解更加深刻
- 提升自己的类库编写能力,尤其是各种边界值的处理
另外有一点需要说明,本文针对的是有一定Promise基础的同学,基础知识不在本文范畴之内,不了解的话请自行Google :)
实现的内容
实现之前我们先来思考下,一个Promise中到底有哪些是必须要实现的?
按照Promise/A+的标准来说,只需要Promise的then方法即可,至于怎么实现、constructor怎么写,完全没有提及。不过虽然看似东西很少,但是实质上还是有蛮多东西要处理的。
首先,constructor是必须的,在这里我们需要做一些初始化的动作:
- 初始状态处理
- 对传入的resolver进行判断并做容错处理
- 执行传入的resolver函数
- 定义resolve、reject函数
其次,then方法由于是每个实例上都有,所以会挂在prototype上面,then方法中我们需要做的事情有
- 对传入的onFulfilled、onRejected进行判断并做容错处理
- 判断当前Promise的状态并返回一个新的Promise
然后,我们还需要一个resolvePromise函数,这个函数根据标准而来(其实不管怎样,Promise的实现中都是少不了这样的处理过程)
至于原型上的catch方法以及race、all等静态方法,暂时不处理,而且这些在我们实现了Promise的基础代码后都是很容易的事情,暂时不做处理。
Constructor
function Promise(resolver) { var self = this self.status = 'pending' self.fulfilledCallbacks = [] self.rejectedCallbacks = [] self.data = null if(typeof resolver !== 'function') { throw new TypeError('Promise resolver ' + resolver + 'is not a function') } function onFulfilled(data) { setTimeout(function