前言
上一篇文章记录了关于promise的一些常规用法,这篇文章尝试基于Promise/A+规范实现一个promise对象。
看个栗子
下面代码是promise的最基本的使用
getRandomNum方法返回一个Promise,可以通过它的then方法注册在promise异步操作成功和失败时执行的回调。
研究其原理
先来大概了解一下promise/A+规范是的要求。
首先,promise 是一个拥有 then 方法的对象或函数,其行为符合本规范;
两个硬性要求:
1、一个 promise 必须提供一个 then 方法以访问其当前值(value)、终值(eventual value)和据因(reason)。
2、一个 Promise 的当前状态必须为以下三种状态中的一种:等待态(Pending)、执行态(Fulfilled)和拒绝态(Rejected)。
先来实现的then方法
promise 的 then 方法接受两个参数:
还有其他几点要求:
1、调用要求:
onFulfilled 和 onRejected 必须被作为函数调用(即没有 this 值)
2、多次调用:
then 方法可以被同一个 promise 调用多次
3、返回:
then 方法必须返回一个 promise 对象
好了,下面开始实现吧!为了易于理解,暂时先不加入onRejected回调参数,在最后会加入。
上述逻辑:
1、调用then方法,将想要在Promise异步操作成功时执行的回调放入callbacks队列;
2、创建Promise实例时传入的函数会被赋予一个函数类型的参数,即resolve,它接收一个参数value,代表异步操作返回的结果,当一步操作执行成功后,用户会调用resolve方法,这时候其实真正执行的操作是将callbacks队列中的回调一一执行;
有一个问题:如果Promise异步操作已经成功,在异步操作成功之前注册的then回调都会执行,但是在Promise异步操作成功这之后调用的then注册的回调就再也不会执行了。
引入状态控制
promise有三种状态:等待态(Pending)、执行态(Fulfilled)和拒绝态(Rejected)。
改进后的代码:
上述代码的思路是这样的:resolve执行时,会将状态设置为fulfilled,在此之后调用then添加的新回调,都会立即执行。
链式调用Promise
如果then函数里面注册的仍然是一个Promise,该如何解决呢??下面的场景应该会经常用到。
实现方案就是在then方法中再返回一个promise对象。
上述过程好像有点复杂,不过多多理解一下就可以完全理解promise了
加入失败状态
|
|
上述代码增加了新的reject方法,供异步操作失败时调用,同时抽出了resolve和reject共用的部分,形成execute方法。
好了一个简单的promise对象就实现了。下面我们看一下能不能用?
总结
按照promise/A+规范实现了核心的一些功能,后续如果有需要可以继续再扩展一些其他方法,可以参考一些比较优秀的库如Q.js,bluebird.js等。