轻松上手 promise 原理 (2):then 的简单实现

用户头像
前端小帅
关注
发布于: 2020 年 06 月 28 日

轻松上手promise原理(2):then的简单实现

在上一篇文章中,我们对于promise有了初步的认识,我们了解到promise是new出来的对象,有三个对应pedding,fulfilled,rejected的状态,在初始化时,拥有status和value和初始化参数executor,executor需要传入resolve和reject函数作为参数。、

在本节我们继续来探索promise的原理,在了解基本的promse构造后,我们来对then方法进一步介绍,我们知道then是用来处理resolve和reject函数的回调。那么首先我们来定义then方法.

##### 1、then方法需要两个参数,其中onFulfilled代表resolve成功的回调,onRejected代表reject失败的回调。

```javascript

then(onFulfilled,onRejected){}

```

##### 2、我们知道promise的状态是不可逆的,在状态发生改变后,即不可再次更改,只有状态为FULFILLED才会调用onFulfilled,状态为REJECTED调用onRejected

```javascript

then(onFulfilled,onRejected){

if(this.status == Promise.FULFILLED){

onFulfilled(this.value)

}

if(this.status == Promise.REJECTED){

onRejected(this.value)

}

}

```

##### 3,then方法的每个方法都不是必须的,所以我们要处理当没有传递参数时,应该设置默认值

```javascript

then(onFulfilled,onRejected){

if(typeof onFulfilled !=='function'){

onFulfilled = value => value;

}

if(typeof onRejected !=='function'){

onRejected = value => value;

}

if(this.status == Promise.FULFILLED){

onFulfilled(this.value)

}

if(this.status == Promise.REJECTED){

onRejected(this.value)

}

}

```

##### 4,在执行then方法时,我们要考虑到传递的函数发生异常的情况,如果函数发生异常,我们应该让它进行错误异常处理,统一交给onRejected来处理错误

```javascript

then(onFulfilled,onRejected){

if(typeof onFulfilled !=='function'){

onFulfilled = value => value;

}

if(typeof onRejected !=='function'){

onRejected = value => value;

}

if(this.status == Promise.FULFILLED){

try{onFulfilled(this.value)}catch(error){ onRejected(error) }

}

if(this.status == Promise.REJECTED){

try{onRejected(this.value)}catch(error){ onRejected(error) }

}

}

```

##### 5,但是现在我们自己封装的promise有个小问题,我们知道原生的promise中then方法都是异步执行,在一个同步任务执行之后再调用,而我们的现在的情况则是同步调用,因此我们要使用setTimeout来将onFulfilled和onRejected来做异步宏任务执行。

```javascript

if(this.status=Promise.FULFILLED){

setTimeout(()=>{

try{onFulfilled(this.value)}catch(error){onRejected(error)}

})

}

if(this.status=Promise.REJECTED){

setTimeout(()=>{

try{onRejected(this.value)}catch(error){onRejected(error)}

})

}

```

##### 现在then方法中,可以处理status为FULFILLED和REJECTED的情况,但是不能处理为pedding的情况,接下来进行几处修改。

##### 6,在构造函数中,添加callbacks来保存pending状态时处理函数,当状态改变时循环调用

```javascript

constructor(executor) {

...

this.callbacks = [];

...

}

```

##### 7,在then方法中,当status等于pending的情况时,将待执行函数存放到callbacks数组中。

```javascript

then(onFulfilled,onRejected){

...

if(this.status==Promise.PENDING){

this.callbacks.push({

onFulfilled:value=>{

try {

onFulfilled(value);

} catch (error) {

onRejected(error);

}

}

onRejected: value => {

try {

onRejected(value);

} catch (error) {

onRejected(error);

}

}

})

}

...

}

```

##### 8,当执行resolve和reject时,在堆callacks数组中的函数进行执行

```javascript

resolve(vale){

if(this.status==Promise.PENDING){

this.status = Promise.FULFILLED;

this.value = value;

this.callbacks.map(callback => {

callback.onFulfilled(value);

});

}

}

reject(value){

if(this.status==Promise.PENDING){

this.status = Promise.REJECTED;

this.value = value;

this.callbacks.map(callback => {

callback.onRejected(value);

});

}

}

```

##### 9,then方法中,关于处理pending状态时,异步处理的方法:只需要将resolve与reject执行通过setTimeout定义为异步任务

```javascript

resolve(value) {

if (this.status == Promise.PENDING) {

this.status = Promise.FULFILLED;

this.value = value;

setTimeout(() => {

this.callbacks.map(callback => {

callback.onFulfilled(value);

});

});

}

}

reject(value) {

if (this.status == Promise.PENDING) {

this.status = Promise.REJECTED;

this.value = value;

setTimeout(() => {

this.callbacks.map(callback => {

callback.onRejected(value);

});

});

}

}

```

到此,promise的then方法的基本实现就结束了,下一篇我们继续来聊关于then的方法,聊一聊promise如何实现then的链式调用。

发布于: 2020 年 06 月 28 日 阅读数: 38
用户头像

前端小帅

关注

前端开发一枚,喜欢吃鸡,王者,打篮球。 2020.06.24 加入

还未添加个人简介

评论

发布
暂无评论
轻松上手promise原理(2):then的简单实现