zoukankan      html  css  js  c++  java
  • 手写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;

     

  • 相关阅读:
    转:关于JAVA多线程同步
    转:Java HashMap实现详解
    索引创建规则:
    数据库为什么要分库分表
    [设计模式] javascript 之 桥接模式
    [百度地图] ZMap 与 MultiZMap 封装类说明;
    [设计模式] Javascript 之 外观模式
    [设计模式] javascript 之 代理模式
    [设计模式] javascript 之 装饰者模式
    [设计模式] javascript 之 适配器模式
  • 原文地址:https://www.cnblogs.com/yuyujuan/p/14549852.html
Copyright © 2011-2022 走看看