You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
constfn=(resolve)=>{setTimeout(()=>{resolve(1);},500);};constpromise1=newPromise(fn);promise1.then((res)=>{console.log(res);// user promisereturnnewPromise((resolve)=>{setTimeout(()=>{resolve(2);},500);});});
前言
在面试的时候,经常会有面试官让你实现一个 Promise,如果参照 A+规范来实现的话,可能面到天黑都结束不了。
说到 Promise,我们首先想到的最核心的功能就是异步链式调用,本篇文章就带你用 20 行代码实现一个可以异步链式调用的 Promise。
这个 Promise 的实现不考虑任何异常情况,只考虑代码最简短,从而便于读者理解核心的异步链式调用原理。
代码
先给代码吧,真就 20 行。
核心案例
本文将围绕这个最核心的案例来讲,这段代码的表现如下:
实现
构造函数
首先来实现 Promise 构造函数
好,写到这里先回过头来看案例
分开来看,
fn
就是用户传的函数,这个函数内部调用了resolve
函数后,就会把promise
实例上的cbs
全部执行一遍。到此为止我们还不知道
cbs
这个数组里的函数是从哪里来的,接着往下看。then
这里是最重要的 then 实现,链式调用全靠它:
再回到案例里
注意这里的命名:
我们把
new Promise
返回的实例叫做promise1
在
Promise.prototype.then
的实现中,我们构造了一个新的 promise 返回,叫它promise2
在用户调用
then
方法的时候,用户手动构造了一个 promise 并且返回,用来做异步的操作,叫它user promise
那么在
then
的实现中,内部的 this 其实就指向promise1
而
promise2
的传入的fn
函数执行了一个this.cbs.push()
,其实是往promise1
的cbs
数组中 push 了一个函数,等待后续执行。那么重点看这个 push 的函数,注意,这个函数在
promise1
被 resolve 了以后才会执行。如果用户传入给 then 的 onResolved 方法返回的是个
user promise
,那么这个user promise
里用户会自己去在合适的时机resolve promise2
,那么进而这里的res.then(resolve)
中的 resolve 就会被执行:结合下面这个例子来看:
then1
这一整块其实返回的是promise2
,那么then2
其实本质上是promise2.then(console.log)
,也就是说
then2
注册的回调函数,其实进入了promise2
的cbs
回调数组里,又因为我们刚刚知道,resolve2
调用了之后,user promise
会被 resolve,进而触发promise2
被 resolve,进而promise2
里的cbs
数组被依次触发。这样就实现了用户自己写的
resolve2
执行完毕后,then2
里的逻辑才会继续执行,也就是异步链式调用。文章总结
本文只是简单实现一个可以异步链式调用的 promise,而真正的 promise 比它复杂很多很多,涉及到各种异常情况、边界情况的处理。
promise A+规范还是值得每一个合格的前端开发去阅读的。
希望这篇文章可以对你有所帮助!
The text was updated successfully, but these errors were encountered: