手写Promise1

Promise就是一个类,在执行这个类的时候,需要传递一个执行器进去,执行器会立即执行。
new Promise(()=>{
    
})

这个回调函数接收两个参数:resolve和reject,这两个函数参数是用来改变状态的:

  • resolve: fulfilled
  • reject: rejected
Promise 中有三种状态,分别为:成功(fulfilled) ,失败 (rejected) 和等待(pending)
  • pending -> fulfilled
  • pending -> rejected
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
    constructor(executor) {
        executor(this.resolve, this.reject)  //立即执行的执行器
    }
    // promsie 状态默认为等待
    status = PENDING;
    resolve = () => {
        // 将状态更改为成功
        this.status = FULFILLED;
    }
    reject = () => {
        // 将状态更改为失败
        this.status = REJECTED;
    }
}

由于Promise一旦状态确定就不可更改。此时,当我们调用了resolve将状态改为成功后,继续调用reject,还是可以将状态改为失败,所以在状态改变前,需要添加判断,如果状态不是等待,则阻止程序向下执行:

const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败
class MyPromise {
    constructor(executor) {
        executor(this.resolve, this.reject)  
    }
    status = PENDING;
    resolve = () => {
        // 如果状态不是等待 阻止程序向下执行
        if (this.status !== PENDING) return;
        this.status = FULFILLED;
    }
    reject = () => {
        // 如果状态不是等待 阻止程序向下执行
        if (this.status !== PENDING) return;
        this.status = REJECTED;
    }
}

 在Promise中,then方法内部做的事情就判断状态:如果状态是成功 ,调用成功的回调函数;如果状态是失败,调用失败回调函数。then方法是被定义在原型对象中的。

then (successCallback, failCallback) {
        //判断状态
        if (this.status === FULFILLED) {
            successCallback();
        }else if(this.status === REJECTED){
            failCallback();
        }
    }
then成功回调有一个参数,表示成功之后的值; then失败回调有一个参数,表示失败后的原因:
const PENDING = 'pending'; 
const FULFILLED = 'fulfilled'; 
const REJECTED = 'rejected'; 

class MyPromise {
    constructor(executor) {
        executor(this.resolve, this.reject)  
    }
    status = PENDING;
    value = undefined; // 成功之后的值
    reason = undefined; // 失败后的原因
    resolve = value => {
        if (this.status !== PENDING) return;
        this.status = FULFILLED;
        this.value = value;
    }
    reject = reason => {
        if (this.status !== PENDING) return;
        this.status = REJECTED;
        this.reason = reason;
    }
    then (successCallback, failCallback) {
        if (this.status === FULFILLED) {
            successCallback(this.value);
        }else if(this.status === REJECTED){
            failCallback(this.reason);
        }
    }
}
module.exports = MyPromise;

  

 在Promise中加入异步逻辑

修改上面的代码,在代码中添加一个延时器

  

 在代码执行过程中,当代码执行到第二行,Promise中的执行器会立即执行。此时,虽然发现了异步代码,但是总线程并不会等待异步代码的执行,而是等主线程的代码执行完毕后再去执行改异步代码,也就是会跳过异步代码,直接执行下面的then方法,此时由于异步的原因,状态并没有立即改变,还是之前的等待状态,所以,还需要在状态判断中,添加一个等待的情况:在等待状态,并不知道将来会是成功还是失败,因此需要临时存储成功和失败的回调,等异步结束后,才能知道是成功还是失败。

const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

class MyPromise {
    constructor(executor) {
        executor(this.resolve, this.reject)
    }
    status = PENDING;
    value = undefined;
    reason = undefined;
    successCallback = []; // 成功回调
    failCallback = []; // 失败回调
    resolve = value => {
        if (this.status !== PENDING) return;
        this.status = FULFILLED;
        this.value = value;
        // 判断成功回调是否存在 如果存在 调用
        this.successCallback && this.successCallback(this.value);
    }
    reject = reason => {
        if (this.status !== PENDING) return;
        this.status = REJECTED;
        this.reason = reason;
        // 判断失败回调是否存在 如果存在 调用
        this.failCallback && this.failCallback(this.reason);
    }
    then(successCallback, failCallback) {
        if (this.status === FULFILLED) {
            successCallback(this.value);
        } else if (this.status === REJECTED) {
            failCallback(this.reason);
        } else {
            //等待状态
            //将成功回调和失败回调存储起来
            this.successCallback = successCallback;
            this.failCallback = failCallback;
        }
    }
}
module.exports = MyPromise;

 

 Promise实现then方法多次调用

 同一个Promise下的then方法是可以被多次调用的,当then方法被多次调用的时候,每一个then方法传递的回调函数都是要被执行的。当多次调用为同步方法时,可以直接调用回调函数就可以了;但是如果时异步的,我们则需要将每一个then方法的回调存储起来,当状态变成成功或者失败后,再依次调用回调函数。

const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

class MyPromise {
    constructor(executor) {
        executor(this.resolve, this.reject)
    }
    status = PENDING;
    value = undefined;
    reason = undefined;
    successCallback = []; 
    failCallback = []; 
    resolve = value => {
        if (this.status !== PENDING) return;
        this.status = FULFILLED;
        this.value = value;
        while(this.successCallback.length) this.successCallback.shift()(this.value)
    }
    reject = reason => {
        if (this.status !== PENDING) return;
        this.status = REJECTED;
        this.reason = reason;
        while(this.failCallback.length) this.failCallback.shift()(this.reason)
    }
    then(successCallback, failCallback) {
        if (this.status === FULFILLED) {
            successCallback(this.value);
        } else if (this.status === REJECTED) {
            failCallback(this.reason);
        } else {
            this.successCallback.push(successCallback);
            this.failCallback.push(failCallback);
        }
    }
}
module.exports = MyPromise;

 

posted on 2021-03-17 17:27  紅葉  阅读(65)  评论(0编辑  收藏  举报