上节课我们已经实现了Promise
的基本结构,两大属性,并且实现了对Promise
的状态和结果的修改,而且也实现then
方法指定回调函数,并对同步异步任务的回调执行分别做了相应的介绍,最后对Promise
指定多个回调也做了相应的实现与分析。
上节课虽然内容很多,但是依然还有一部分因为篇幅的问题,我们还没有介绍到,那么接下来,我们将对另外一部分的功能实现来做进一步的介绍。
同步任务then
方法返回结果
我们之前的内容中就已经介绍过,Promise
对象调用then
方法返回的结果将会是一个新的Promise
对象。那么我们目前的情况的话有没有实现这一功能呢?我们来测试一下:
let p = new Promise( (resolve, reject) => resolve("OK") ); let result = p.then( value => console.log(value), reason => console.warn(reason) ); console.log(result);
我们来看这段代码,首先我们实例化一个Promise
对象,在这个对象中我们封装的是一个同步任务,然后调用then
方法来指定回调,并且声明一个result
变量来接收then
方法的返回值,并且把返回值输出到控制台,那么我们来看一下结果:
控制台中输出的是一个undefined
,为什么呢?因为我们定义了then
方法,但是我们的then
方法并没有返回值,所以说默认返回的就是一个undefined
。
那么我们先来回顾一下then
方法返回一个新的Promise
对象的设计哲学是什么样子的:
then
方法返回的Promise
对象是一个新的Promise
对象then
方法返回的Promise
对象的状态和结果都取决于回调函数执行的结果- 回调函数执行的结果分为三种情况
- 返回非
Promise
类型数据,then
方法将返回一个成功的Promise
对象,结果值为回调函数的返回值 - 返回
Promise
对象,then
方法将返回一个状态和结果值都与回调函数返回值一直的Promise
对象 - 抛出异常,
then
方法将返回一个失败的Promise
对象,结果值为异常字符串
那么我们来修改一下代码吧,首先返回一个新的Promise
对象:
Promise.prototype.then = function (onResolved, onRejected) { return new Promise((resolve, reject) => { if (this.PromiseState === "fulfilled") { onResolved(this.PromiseResult); } if (this.PromiseState === "rejected") { onRejected(this.PromiseResult); } if (this.PromiseState === "pending") { this.callbacks.push({ onResolved, onRejected }); } }); };
我们用最简单的方法就直接在return
的时候new
一个新的Promise
对象。但是我们之前then
方法中的代码还是要执行的啊,那么就应执行器函数来包裹住之前的代码,可能有人会问,我们能不能把之前代码放在return
之前呢?就目前来说是没有问题的,因为之前then
方法中的内部代码也都是同步代码,那么在return
之前或者是用执行器函数包裹住都没有区别,因为执行器函数也是立即同步被执行的。我们来看一下结果是什么样:
我们看到控制台中输出的不再是undefined
了,而是一个Promise
对象,那么现在我们实现了第一条,then
方法返回的是一个新的Promsie
对象。但是有一点,我们这里输出的Promise
对象的状态和结果值好像都有点问题。
我们来看我的第二条,then
方法返回的Promise
对象的状态和结果值都取决于回调函数的执行结果。那么我们来看一下我们的回调函数是什么,我们执行的是value => console.log(value)
,首先这个函数没有返回值,其次,控制台上也成功输出了value
,说明回调函数没有抛出异常。
那么好,我们来看一下第三条,有三种情况,那么这属于那种情况呢?没有返回值就是undefined
,而且也没有抛出异常,是不是刚好就是第一种情况,返回了非Promise
类型的数据?那么我们就应该返回一个成功的Promise
对象,而且结果值为回调函数的返回值,也就是undefined
,那么我们再来修改一下代码:
Promise.prototype.then = function (onResolved, onRejected) { return new Promise((resolve, reject) => { if (this.PromiseState === "fulfilled") { let result = onResolved(this.PromiseResult); resolve(result); } if (this.PromiseState === "rejected") { let result = onRejected(this.PromiseResult); reject(result); } ... }); };
我们来看这段代码是什么意思呢?根据Promise
设计哲学的第二条,then
方法返回的Promise
对象的状态和结果值由回调函数的执行结果来决定。
我们在第一步实例化的Promise
对象p
的状态是个什么状态?是不是一个成功的Promise
?那么在调用then
方法的时候是不是一定会根据状态去调用onResolved
函数?这个onResolved
函数是哪来的?是不是就是我们调用then
方法时候传进去的,那么这里的话是不是就是value => console.log(vale)
?那么这个函数的返回值是不是就应该是then
方法返回的Promise
对象的结果值?那么我们声明一个变量result
来接收这个返回值。
那么接下来问题来了,我们结果值有了,但是then
方法返回的Promise
对象的状态我们该怎么修改呢?首先我们的then
方法返回的是什么?是不是我们这里new
出来的一个新的Promise
?那么一个Promsie
如果想改变状态要怎么做?这很简单啊,直接在执行器函数中去调用resolve
或者reject
函数就可以了,因为第一种情况永远返回的都是一个成功的Promise
啊,这样我们调用resolve
函数,并把result
传进去一次性把状态和结果值都解决了。
所以说通过这一部分的分析,我们再回头来思考刚才的问题,我们then
方法中的状态判断的这部分代码可以放在return
之前吗?好像也可以,但是会比直接放在执行器函数中要麻烦许多。
那么我们现在再看一下结果:
我们看见了现在我们的输出好像还是有点问题,当我们第一步实例化的Promise
的状态是rejected
的话,我们是应该调用onRejected
函数的,我们这里指定的onRejecte
函数是什么?reason => console.warn(reason)
,这个回调函数也没有返回值啊,那么也是undefined
,所以then
方法返回的应该也是一个成功的Promise
,但是我们输出的却是一个失败的Promise
。
不知道大家在看完上面那段代码的时候有没有发现一个错误,我这里先不说是什么错误,我先把代码修改一下:
Promise.prototype.then = function (onResolved, onRejected) { return new Promise((resolve, reject) => { if (this.PromiseState === "fulfilled") { let result = onResolved(this.PromiseResult); if (result instanceof Promise) { ... } else { resolve(result); } } if (this.PromiseState === "rejected") { let result = onRejected(this.PromiseResult); if (result instanceof Promise) { ... } else { resolve(result); } } ... }); };
大家来看这段代码,有没有发现和之前代码有什么不一样的地方?我们的回调函数的返回值是不是有两种情况?一种是Promise
对象,另一种不是Promise
对象,当不是Promise
对象时,then
方法将永远返回一个成功的Promsie
,之前的代码中我们忘了做判断。
现在我们对回调函数的返回值的类型来做一个判断,当回调函数返回值不是一个Promise
对象时,不论第一步实例化的Promise
对象是否成功都调用resolve
函数来改变新的Promise
的状态和结果值。
那么如果回调函数返回的是一个Promise
对象的话,又该怎么处理呢?我们知道如果回调函数返回的是一个Promsie
对象的话那么这个Promsie
对象的状态和结果值就是then
方法返回的Promise
对象的状态和结果值。那么我们应该怎么处理呢:
Promise.prototype.then = function (onResolved, onRejected) { return new Promise((resolve, reject) => { if (this.PromiseState === "fulfilled") { let result = onResolved(this.PromiseResult); if (result instanceof Promise) { result.then( value => resolve(value), reason => reject(reason) ); } ... } if (this.PromiseState === "rejected") { let result = onRejected(this.PromiseResult); if (result instanceof Promise) { result.then( value => resolve(value), reason => reject(reason) ); } ... } if (this.PromiseState === "pending") { this.callbacks.push({ onResolved, onRejected }); } }); };
我们来看代码,这是什么操作呢?我们来想一下,如果回调函数返回的是一个Promise
对象的话,那么这个Peomise
对象是不是肯定可以调用then
方法?那么是不是就代表着我们可以通过then
方法来指定让这个Promise
对象分别在成功和失败的时候来调用resolve
函数和reject
函数来修改then
方法返回的Promsie
对象的状态和结果值?
let result = p.then( value => { console.log(value); return new Promise((resolve, reject) => { resolve("OK") }); }, reason => { console.warn(reason); return new Promise((resolve, reject) => { reject("error"); }); } ); console.log(result);
那么我们这次来让成功和失败的回调分别返回一个成功和失败的Promsie
对象,我们再来看一下结果:
第一步实例化的Promise
对象是个成功的Promise
,然后执行成功时的回调,回调函数返回一个成功的Promise
对象,结果值是OK
,我们看见控制台中输出的Promise
对象的状态和结果值与回调函数返回的Promise
对象一致。
现在我们第一步实例化的Promise
对象是一个失败的Promsie
,然后执行失败时的回调,回调函数返回一个失败的Promise
对象,结果值是error
,我们看见控制台中输出的Promsie
对象的状态和结果值与回调函数返回的Promise
对象一直。
这样我们便实现了Promise
设计哲学中then
方法返回值规则的第一条,第二条以及第三条的前两种情况。
那么第三种情况呢?我再回调函数中抛出异常的话应该怎么处理呢?
Promise.prototype.then = function (onResolved, onRejected) { return new Promise((resolve, reject) => { if (this.PromiseState === "fulfilled") { try { let result = onResolved(this.PromiseResult); ... } catch (e) { reject(e); } } if (this.PromiseState === "rejected") { try { let result = onRejected(this.PromiseResult); ... } catch (e) { reject(e) } } ... }); };
为了节省篇幅我就把部分代码省略了,将之前的代码全部放在try
代码块中,然后用catch
来捕获回调函数中的异常,当回调函数中抛出异常时,将直接调用reject
函数来修改状态。
以上便是对Promise
同步任务调用then
方法返回一个新的Promsie
对象的实现。
异步任务then
方法返回结果
我们前面说了同步任务的then
方法返回结果。但是Promise
异步任务的then
方法返回情况,根据我们之前的经验来看肯定适合同步任务是不一样的,我们来回想一下我们之前让then
方法调用回调函数的时候是什么情况?
- 同步任务直接在
then
方法函数体中判断resolved
和rejected
状态,并直接执行回调 - 异步任务在修改状态之前
then
方法已经完成调用,但是resolved
和rejected
状态都匹配不上,所以要在then
方法中判断pending
状态并保存传入的回调函数,然后在Promsie
状态发生改变之后才执行回调函数
那么现在then
的返回值情况我们来看一下是什么样子:
let p = new Promise( (resolve, reject) => setTimeout( () => resolve("OK"), 1000 ) ); let result = p.then( value => { console.log(value); }, reason => {...} ); console.log(result);
我们来看代码,我们实例化了一个Promise
对象,并开启一个异步任务,让Promise
对象延迟一秒将状态修改为成功,然后我们来看一下then
方法返回的结果:
我们发现返回的结果并不符合我们的预期,为什么呢?是不是和之前执行回调函数一样?因为执行then
方法的时候我们还没有执行回调函数,那么就会去判断pending
状态,但是pending
状态中我们只是存储回调函数到我们第一步实例化的Promise
对象上,而回调在执行的时候修改的也是我们第一步实例化的Promise
对象的状态,所以说我们then
方法返回的就是一个没有改变过状态还结果值的Promise
对象。
那么我接下来的思路是不是就要在pending
状态这个分支来做手脚了?那么我们怎么处理呢?
Promise.prototype.then = function (onResolved, onRejected) { return new Promise((resolve, reject) => { ... if (this.PromiseState === "pending") { this.callbacks.push({ onResolved: () => { let result = onResolved(this.PromiseResult); if (result instanceof Promise) { } else { resolve(this.PromiseResult); } }, onRejected: () => {...} }); } }); };
我们来看代码,我们这里为了节省篇幅就把之前的代码省略了,我们来看对pending
状态的判断分支,首先最外层我们依然还是哪个操作,我们要把回调封装成对象存储到第一步实例化的Promise
对象的callbacks
属性上。
但是我们对回调函数的封装可就不能像原来一样了,我们定义一个函数,在这个函数中执行回调,那么这个回调被执行的结果就可以决定then
方法返回的Promise
对象的状态和结果。
那么我们接下来就要通过这个回调的执行结果来修改then
方法要返回的Promise
对象的状态。那么我们是不是也要判断回调返回值的类型?如果返回的不是Promise
对象,那就把then
返回的Promise
对象状态改为成功。我们来看一下结果:
我们看见现在我们回调现在返回的都不是Promise
对象,输出结果也都是没有问题的,那么如果回调函数返回的是一个Promise
对象的话呢?那和同步任务是不是也类似?既然回调返回的是Promise
对象,那么就可以调用then
方法,那么我们根据then
方法来进行相关的处理就可以了,包括回调函数抛出异常也是和同步任务的处理一样,大家尝试自己来补全代码,都是同一个原理,这里就不再赘述了
以上我们便实现了异步任务的then
方法返回一个新的Promise
对象。
可能大家在写完之后会发现我们好像写了好多重复代码啊,我希望大家能有自己优化代码的能力,我最后将会我的完整代码放在我的git
仓里,大家有需要的可以来参考,我这里就不贴代码了。
catch
方法以及异常穿透
我们现在基本算是已经实现了then
方法了,但是我们还有一个很重要的功能,就是异常穿透。因为我们then
方法是要进行链式调用的啊,如果调用链中间某一环出现了异常我们没有异常穿透的话在每一环都要catch
一下才行,那么我们异常穿透要怎么实现呢?首先肯定要实现catch
功能,那么我们现在如果在then
方法后面调用catch
的话会怎么样呢?
let p = new Promise((resolve, reject) => { setTimeout(() => reject("error"),1000); }); p.then( value => console.log(111) ).then( value => console.log(222) ).catch( reason => console.warn(reason) );
我们先这样实例化一个Promise
对象,并且让Promise
对象状态为失败,而我们链式调用then
方法,而且只指定成功时的回调,我们来看一下结果是什么样子,按照预期的话应该会被catch
方法捕获:
报错了,告诉我们catch
不是一个函数,为什么呢?因为我们根本都没有给Promise
来添加一个catch
方法啊,所以这里肯定是会报错的,那么我们就把这个catch
方法给加上:
Promise.prototype.catch = function (onRejected) { return this.then(undefined, onRejected); }
我们之前在介绍catch
方法的时候就说过,catch
是把then
方法做了一个独立封装,而且catch
只接收一个函数类型的参数,并且会返回一个失败状态的Promise
对象,那么我们就直接拿then
方法来封装就好了,我们来看一下结果:
现在不报错了,但是我们的输出结果好像不太对劲。我们应该输出error
才对啊,这是为什么呢?我们来分析一下,我们Promise
对象里面开的是异步任务对不对?那么调用then
的时候是不是状态还没改变?然后就把我们指定的回调都保存到实例对象上了?但是我们是不是根本没有指定失败时的回调啊?那么当我们这个Promise
的异步任务执行完成之后,把Promise
的状态修改成了失败,那么肯定要去调用失败时的回调,但是我们没有指定失败时的回调,使用就输出了这么个问题。
但是Promise
是允许我们在链式调用中只指定一个回调另一个回调不传的,但是不传不代表Promise
内部底层没有,不然的话我们传undefined
进去也肯定会报错的,那么我们是不是也应该在then
方法中来做一个相应的处理来解决这个问题呢?
Promise.prototype.then = function (onResolved, onRejected) { if (typeof onRejected !== "function") { onRejected = reason => { throw reason; }; } if (typeof onResolved !== "function") { onResolved = value => value; } return new Promise((resolve, reject) => {...}); };
我们来看这段代码,我们判断了一下onRejected
和onResolved
这两个形参的类型,如果是函数那就继续,如果不是函数,那么我们就来指定一个默认函数,onRejected
指定的默认函数大家应该都能明白,如果onRejected
传入进来不是函数,那么通常可能代表着我们没有传这个参数,那么我们如果异步任务是失败的,但是我们却没有传这个回调,那么我们就抛出一个异常让catch
去捕获。
但是onResolved
指定的默认函数是什么意思呢?这个是Promise
的一个值传递,比如我这个Promise
对象是成功的,但是我在调用then
的时候并没有指定成功时的回调函数,那么就将通过这个默认函数来传递value
值供then
方法来返回一个新的Promise
对象来进行接下来的链式调用。
那么我们现在来看一下失败时会怎么样:
现在catch
方法成功被调用并输出了我们预期的结果。那么我们来测一下成功时的值传递:
let p = new Promise((resolve, reject) => { setTimeout(() => resolve("OK"),1000); }); p.then( ).then( value => console.log(222) ).catch( reason => console.warn(reason) );
这次我们在then
方法调用链的第一环并没有指定任何回调,来看一下结果:
成进行了后面的链式调用并输出了相应结果。以上便是我们对catch
方法以及异常穿透的实现。
resolve
和reject
函数的封装
看到这个标题大家可能会很奇怪,resolve
和reject
函数不是早就封装好了吗?这里的resolve
和reject
函数和我们之前说的不是一回事,之前的是Promise
函数里的内置函数,这里是指Promise
的API
中的Promise.resolve
和Promise.reject
。那么我们首先先看一下我们目前直接调这两个方法会是什么结果:
报错了说resolve
和reject
不是一个函数,为什么呢?因为我们没有给Promise
添加resolve
和reject
方法,那么我们现在来把这两个方法添加上:
Promise.resolve = function(value){ } Promise.reject = function(reason){ }
我们要注意一点,我们在给Promise
添加resolve
和reject
方法时要明确一点就是这两个方法是Promise
函数对象的,而不是Promise
实例对象的,所以我们不能用Promise.prototype
,好了现在我们有了这两个方法了,我们来回忆一下这两个方法是用来干什么的。
Promise.resolve
将返回一个成功或者失败的新的Promise
对象- 如果传入的参数不是
Promise
对象,则返回一个成功的Promise
对象,且结果值是我们传入的value
- 如果传入的参数是一个
Promise
对象,则返回一个状态和结果值都与传入的Promise
对象相同的新的Promise
对象 Promise.reject
将返回一个失败的新的Promise
对象,且返回的Promise
对象的结果值就是我们传入的值
那么我们应该这么实现我们这两个方法的内部逻辑呢?我们来看一下代码:
Promise.resolve = function (value) { return new Promise((resolve, reject) => { if (value instanceof Promise) { value.then( v => resolve(v), r => reject(r) ); } else { resolve(value); } }); } Promise.reject = function (reason) { return new Promise((resolve, reject) => reject(reason)); }
首先来看两个函数的最外层的操作,我们都return
一个新的Promise
对象,先来看resolve
,我们传入了value
,有两种情况,Promise
对象,或者不是Promise
对象,那么我们就要判断一下,如果不是Promise
对象,就直接调resolve
函数修改状态,如果是Promise
对象,那就调用then
方法在回调里面修改状态
然后我们来看reject
函数,这个就简单了,因为reject
函数只会返回一个失败的Promise
而且我们传什么,结果值就是什么,那么直接调用reject
来改状态就好了。
let p1 = Promise.resolve("OK"); let p2 = Promise.resolve(new Promise((resolve, reject) => reject("OH NO"))); let p3 = Promise.reject("Error"); let p4 = Promise.reject(new Promise((resolve, reject) => reject("F**K"))); console.log(p1); console.log(p2); console.log(p3); console.log(p4);
我们现在用这两个方法来生成了 4 个Promise
对象,然后输出到控制台上我们来看一下结果:
我们看到我们控制台中输出了相应的结果也是完全符合Promise
规则的。
以上便是resolve
和reject
函数的封装。
all
方法的封装
前面我们实现了then
,catch
,resolve
,reject
以及多个核心功能,其实到这自定义封装距离结束已经不远了,接下来呢我们来介绍一下all
方法的封装。
首先我们来回忆一下all
方法是干什么的。这个方法也是Promise
函数对象自身的一个方法,接收一个Promise
实例对象的数组,并返回一个新的Promise
对象,如果数组中所有Promise
对象都是成功的,那么返回的新的Promise
就是成功的,而且结果值是数组中所有Promise
对象的结果值组成的数组。如果数组中有失败的Promise
对象,那么返回的Promise
对象的状态就是失败的,而结果值则是失败的那个Promise
对象的结果值。
那么我们就不做测试了,我们现在还没有给Promise
函数添加all
方法,直接测试肯定报错,我们先来添加方法吧。
Promise.all = function (promises) { return new Promise((resolve, reject) => { }); }
我们来看一下,这样我们就实现了all
方法的一个基本结构,但是这样的话肯定不符合我们的需求的,首先我们接收的形参是一个数组,而且只有当数组中的Promise
对象都是成功的时候才能把我们返回的Promise
对象状态修改为成功。那么我们怎么判断数组中的Promise
对象是不是都是成功的?那么是不是要for
循环?
Promise.all = function (promises) { return new Promise((resolve, reject) => { for (let i = 0; i < promises.length; i++) { promises[i].then( value => { }, reason => reject(reason) ); } }); }
我们来看这段代码,我们遍历整个数组,这个数组里面所有的元素都是Promise
对象,那么只要是Promise
对象那么就可以调用then
方法,然后我们来指定回调,成功的回调函数我现在还没有实现,我们先来看失败的回调,all
方法的逻辑是什么?只有数组中有任何一个失败的Promise
对象,那么就不用再考虑其他的了,直接返回一个失败的Promise
对象,而且结果值就是这个失败的Promise
对象的结果值,那么我们是不是直接调用reject
函数来修改状态就行了?我们来测试一下:
let p1 = Promise.resolve("OK"); let p2 = Promise.reject("Error"); let p3 = Promise.resolve("Yes"); let result = Promise.all([p1, p2, p3]); console.log(result);
我们创建了三个Promise
对象,其中有一个是失败的,看一下结果:
我们看到控制台输出的是一个失败的Promise
对象,而且结果值就是失败的那个Promise
对象的结果值,那么如果三个都是成功的应该这么实现呢?
Promise.all = function (promises) { return new Promise((resolve, reject) => { let count = 0; let result = []; for (let i = 0; i < promises.length; i++) { promises[i].then( value => { count++; result[i] = value; if (count === promises.length) resolve(result); }, reason => reject(reason) ); } }); }
我们这次来看这段代码,我们在for
循环中肯定是不能直接执行resolve
函数的,因为我们要等到确定所有的Promise
对象都是成功的才能执行resolve
函数,所以我们预先声明一个变量,每当成功的回调被执行都让它自增,等到这个变量和数组长度相等的时候那是不是就代表着整个数组里面都是成功的Promise
,那么我们就可以执行resolve
函数了。
但是我们现在可以修改状态了,但是结果值呢?我们说了如果全是成功,返回的结果值是这些数组里所有Promise
对象的结果值组成的数组。那么我们就要预先声明一个数组用于存放结果值,但是我们这里为什么没有用push
方法向数组里面添加结果呢?
因为结果值数组的顺序要和promises
数组顺序一致,这样的话就可以保证不会因为异步任务完成的时间不同而导致顺序错乱,那么我们 这次用三个成功的Promise
对象来测一下:
我们看见这次输出的Promise
对象是一个成功的,而且结果值也是按照之前顺序的一个数组。以上我们便完成了对all
方法的封装。
race
方法的封装
接下来我们来实现最后一个API
,race
方法和all
方法很像,但是race
方法不用像all
方法那样来确定数组中每个Promise
对象的状态,这是一个数组中的Promise
对象赛跑的机制,谁最先改变状态,谁的状态和结果值就是race
方法返回的Promise
的状态和结果值,那么就简单了,我们先来添加方法:
Promise.all = function (promises) { return new Promise((resolve, reject) => { for (let i = 0; i < promises.length; i++) { promises[i].then( value => resolve(value), reason => reject(reason) ); } }); }
我们来看一下代码,可能有人要问,这次我们为什么不计数了呢?因为用不着了,我们这里的返回值状态取决于第一个改变状态的Promise
对象,所以说直接改就行了那么我们来测一下:
let p1 = new Promise((resolve, reject) => setTimeout(() => reject("Error"), 1000)); let p2 = Promise.resolve("It's OK"); let p3 = Promise.reject("OH NO"); let result = Promise.all([p1, p2, p3]); console.log(result);
我们这次让第一个Promise
对象封装一个异步任务,那么我们来分析一下哪个Promise
对象最先改变状态,首先肯定不是p1
对吧,因为p1
开了异步任务,要等 1 秒才能修改状态,那么来到p2
,这是个同步的,直接就修改了状态,然后才执行p3
所以说结果输出的应该是一个成功的Promise
对象,结果值和p2
的结果值一致:
如此一来我们便实现了Promise
中所有的API
。
then
回调函数异步执行
我接下来来实现一个细节上的东西。我们先来看Promise
的一个细节:
let p = new Promise((resolve,reject)=>{ resolve("OK"); console.log(111); }); p.then(v=>console.log(222)); console.log(333);
我们来看一下Promise
的结果是什么样子:
我们看控制台上输出的内容好像和我想的不一样啊,因为Promise
在设计的时候是吧then
中的回调异步执行的,那我们来看一下我们自己手写的Promise
:
我们自己写的好像和Promise
的设计不符合啊,那么我们用setTimeout
函数来把我们回调调用部分包裹起来是不是就实现异步了?代码我这里就不贴了,大家自己尝试实现一下。
理论上我们接下来要介绍一下怎么把我们的Promise
封装成一个类,因为到现在为止我们都是函数式编程,但是我觉得大家可以自己尝试把函数式编程封装成类,我们这里就不赘述了。
Copyright statement:The articles of this site are all original if there is no special explanation, indicate the source please when you reprint.
Link of this article:https://work.lynchow.com/article/lesson07_encapsulation_of_promise2/