es6 一经推出,Promise 就一直被大家所关注。那么,为什么 Promise 会被大家这样关注呢?答案很简单,Promise 优化了回调函数的用法,让原本需要纵向一层一层嵌套的回调函数实现了横向的调用,也就是链式调用。
既然 Promise 这么好用,那它背后的的实现原理是什么呢?要知道,作为一个有追求的程序猿,不仅要知其然,还要知其所以然,ok ,下面我就来简单模拟一下 Promise 的实现!
首先,我们要知道 Promise 的基本用法是怎样的。
好,知道了 Promise 的基本用法(我就当你们都会用 ^ ^),那么我们就来模拟一下它。
第一步,当然是要一个构造函数了,为了语义化,我就给它命名为 _Promise
我来解释一下这个构造函数李的属性都是用来干什么的。首先,作为构造函数的参数传进来的 resolver,它是一个函数 ,当 _Promise被实例化的时候, resolver 函数会立即执行,它接受两个参数,分别是 resolve 和 reject。resolve 和 reject 就是执行成功和执行失败的函数。this._status 是 _Promise 的内部状态,初始化为 ‘pending’,resolve 函数执行的时候 会把它的值 从 ‘pending’ 变成‘fullfilled’,这也就是说 _Promise 执行成功,反之,reject函数会把它的值 从 ‘pending’ 变成 ‘rejected’。一旦 this._status 的值发生发生了改变之后,它的值就会保持不变,也就是说,它的值 会一直保持在 ‘fullfilled’ 或 ‘rejected’ 状态 。this._result 是在 rolve 或者 reject 的时候 需要传递给 then 函数的值。
好,接下来我们来看 resolve 和 reject 函数。先上图:
resolve 和 reject 函数,在这里我是直接fanf放在了 _Promise 的原型对象上。当它们被调用的时候,首先需要判断 _Promise的 _status 是不是为 ‘pending’ ,只有在 _status 的值是 ‘pending’ 的时候才会进行后面的操作。当 _status 的值为‘pending’的时候,resolve 函数会把 _status的值变成 ‘fullfilled’,如果是 reject 被执行,那么它就会把 _status 的值变成 ‘rejected’。同时,resolve 和 reject 函数都会把传递进来的参数 result 赋值给 this._result ,而这个值会被 之后的 then 函数拿到。
ok ,接下来看看 then 函数。
和 resolve 和 reject 函数一样,then函数也是直接定义在 _Promise 的原型对象上的。
then函数接收两个参数,分别是 isResolve 和 isReject ,顾名思义,分别是 resolve (成功)和 reject(失败) 时调用的函数。因为考虑到 可能会出现多次链式的调用,比如 Promise.then().then().then()这样的,所以 then 函数 要返回来 一个 _Promise.
那么 then函数返回来的 _Promise 是哪个呢。这就要看 isResolve 和 isRejected 执行的结果了,如果它们返回来了一个新的 _Promise,那么我们就需要把这个新的 _Promise 给它 return 出去。
比如这样的时候:
所以我们就需要判断一下 isResolve 函数和 isReject 函数的执行结果
如果返回的值不是一个新的 _Promise ,那么我们就把当前的 _Promise 实例返回,也就是 this .
到了这里,_Promise的模拟也就差不多完成了。还剩下一点,那就是 es6 中 Promise 有一个 catch 函数,我在这里也简单模拟了一下,它是专门给 reject 使用的 。
你可以像这样使用它:
好了,到此为止, Promise的模拟就全部完成了。如果大佬们发现了有什么不足或者错误的地方,欢迎在下面留言,我们一起来讨论~~~~