手写一款相符Promise/A+范例的Promise

手写一款相符Promise/A+范例的Promise

长篇预警!有点长,能够选择性寓目。假如对Promise源码不是很清晰,照样引荐从新看,相信你仔细从新看到尾,而且去实际操纵了,一定会有收成的。主如果代码部份有点多,不过许多都是反复的,没必要忧郁

Promise的一些用法在此不多赘述,本篇重要率领你手写一个Promise源码,学完你就会发明:Promise没有你设想中的那末难

本篇也许分为以下步骤

  • 完成简朴的同步Promise
  • 增添异步功用
  • 增添链式挪用then
  • 增添catch finally要领
  • 增添all race 等要领
  • 完成一个promise的耽误对象defer
  • 终究测试

完成简朴的同步Promise

先也许说一下基本概念:
Promise内部维护着三种状况,即pending,resolved和rejected。初始状况是pending,状况能够有pending—>relolved,或许pending—>rejected.不能从resolve转换为rejected 或许从rejected转换成resolved.
即 只需Promise由pending状况转换为其他状况后,状况就不可变动。
ok.知道了这些后,我们最先手撸代码:

注重寓目序号 1 2 3 4 5 …



function Promise(executor){
    let that = this;
    /** 2 定义初始的一些变量 */
    that.status = 'pending';
    that.value = null;
    that.reason = null;
    
    /** 3 定义初始的胜利和失利函数 */
    function resolve(value){
        /** 4 推断状况是不是是初始状况pending 
         *    是就转换状况 否则不转换 
         *    确保状况的变化后的不可变性 */
        if(that.status === 'pending'){
            that.status = 'resolved';
            that.value = value;
        }
    }
    function reject(reason){
        /** 5 同上 */
        if(that.status === 'pending'){
            that.status = 'rejected';
            that.reason = reason;
        }
    }
    /**
     * 1 Promise中起首传了一个executor,它是一个函数
     *   executor函数中又传了两个函数,分别是resolve和reject
     *   很显然 resolve是胜利回调,reject是失利的回调
     */
    executor(resolve,reject);
}

/** 6 在Promise原型上面定义then要领
 *    then要领上面有两个回调 一个是胜利后的要领 另一个是失利后的要领
 *    依据胜利或失利的状况去实行相干胜利onFilfulled()或许失利onRejected()的回调要领
 */
Promise.prototype.then = function(onFilfulled,onRejected){
    let that = this;
    if(that.status === 'resolved'){
        /** 7 假如状况已变动为resolved 
         *    申明resolve要领已被挪用
         *    那末此时就实行胜利的回调函数onFilfulled
         *    并传入参数 that.value
         * */
        onFilfulled(that.value);
    }
    if(that.status === 'rejected'){
        /** 8 同上
         *    传入参数 that.reason
         */
        onRejected(that.reason);
    }
}

module.exports = Promise;

经由历程require()引入手撸的Promise

let Promise = require('./myPromise');

let p1 = ()=>{
    return new Promise((resolve,reject)=>{
        resolve('success.1');
    });
}

p1().then((data)=>{
    console.log(data); // 打印 success.1
},(err)=>{
    console.log(err);
});

ok.经挪用发明 此代码能够完成部份Promise的功用,但仅仅是同步下才有效果。
那异步呢? 别急这就来~:

增添异步功用

注重寓目序号 1 2 3 4 5 …



function Promise(executor){
    let that = this;
    that.status = 'pending';
    that.value = null;
    that.reason = null;
    /** 1 由于异步不是马上实行 状况不会变动 胜利或失利的回调函数也不会实行
     *    所以先定义好寄存胜利或失利回调函数的数组 
     *    以便将胜利或失利的回调函数先保存起来
     * */
    that.onFilFulledCallbacks = [];
    that.onRejectedCallbacks = [];

    function resolve(value){
        if(that.status === 'pending'){
            that.status = 'resolved';
            that.value = value;
            /** 3 宣布
             *    守候状况发作变动
             *    状况变动后 马上实行之前寄存在响应数组中一切的胜利或失利的回调函数
             *    即 宣布
             */
            that.onFilFulledCallbacks.forEach((fn)=>{
                fn();
            });
        }
    }
    function reject(reason){
        if(that.status === 'pending'){
            that.status = 'rejected';
            that.reason = reason;
            /** 4 同上 */
            that.onRejectedCallbacks.forEach((fn)=>{
                fn();
            });
        }
    }
    executor(resolve,reject);
}

Promise.prototype.then = function(onFilfulled,onRejected){
    let that = this;
    if(that.status === 'resolved'){
        onFilfulled(that.value);
    }
    if(that.status === 'rejected'){
        onRejected(that.reason);
    }
    /** 2 定阅
     *    由于是异步 状况当时并没有马上变动 所以状况照样pending
     *    此时须要把胜利或许失利的回调函数寄存到对应的数组中
     *    守候状况变动时 再从数组中拿出往来来往实行
     *    即 定阅
     *    *寄存数组时 为了实行时轻易 须要把回调函数的外层包裹一层空函数
     */
    if(that.status === 'pending'){
        that.onFilFulledCallbacks.push(function(){
            onFilfulled(that.value);
        });
    }
    if(that.status === 'pending'){
        that.onRejectedCallbacks.push(function(){
            onRejected(that.reason);
        });
    }
}

module.exports = Promise;

代码测试:

let Promise = require('./myPromise');

let p1 = ()=>{
    return new Promise((resolve,reject)=>{
        setTimeout(function(){
            resolve('success.1');
            // reject('fail.');
        },1500);
    });
}

p1().then((data)=>{
    console.log(data); // success.1
},(err)=>{
    console.log(err);
});

能够看到 1.5s后 实行了resolve() 并打印了success.1,至此,我们完成了异步的Promise.实在这里的完成异步的头脑就是宣布定阅.

en~ok.高能预警🐯.接下来就稍稍庞杂了 由于我们要完成链式挪用then。 要完成这个功用那我们就要重写then要领,并在then要领中从新返回一个Promise,只要如许,才能够完成屡次挪用then.而且要新增一个剖析返回值是不是为promise的函数.

轻微捋下逻辑:

  • 假如一个then要领返回一个一般值的话,这个值会通报给下一个then中作为resolve胜利的效果
  • 假如一个then要领返回一个promise的话,会依据返回的promise是胜利照样失利,决议下一个then是胜利照样失利

👌 上代码:

增添链式挪用then

注重寓目序号 1 2 3 4 5 …



function Promise(executor){
    let that = this;
    that.status = 'pending';
    that.value = null;
    that.reason = null;
    that.onFilFulledCallbacks = [];
    that.onRejectedCallbacks = [];

    function resolve(value){
        if(that.status === 'pending'){
            that.status = 'resolved';
            that.value = value;
            that.onFilFulledCallbacks.forEach((fn)=>{
                fn();
            });
        }
    }
    function reject(reason){
        if(that.status === 'pending'){
            that.status = 'rejected';
            that.reason = reason;
            that.onRejectedCallbacks.forEach((fn)=>{
                fn();
            });
        }
    }
    executor(resolve,reject);
}

Promise.prototype.then = function(onFilfulled,onRejected){
    let that = this;
    /** 1 让promise2即是一个新的Promise 并将promise2返回 */
    let promise2 = new Promise((resolve,reject)=>{
        if(that.status === 'resolved'){
            /** 2 由于返回了promise2 
             *  而且第3步resolvePromiseRelation函数中通报了promise2
             *  而现在promise2并没有拿到
             *  所以加一个定时器 异步实行 比及promise2拿到后 
             *  再去实行 resolvePromiseRelation()要领 并将promise2通报进去*/
            setTimeout(()=>{
                try{
                    let promise3 = onFilfulled(that.value);
                    /** 3 推断新返回值是什么范例的函数
                     *  并将当前的promise:promise2  新的返回值:promise3 
                     *  和 胜利时回调:esolve  失利时回调:reject 作为参数传进去 */
                    resolvePromiseRelation(promise2,promise3,resolve,reject);
                }catch(e){
                    reject(e);
                }
            },0);
        }
        if(that.status === 'rejected'){
            /** 同2 */
            setTimeout(()=>{
                try{
                    let promise3 = onRejected(that.reason);
                    /** 同3*/
                    resolvePromiseRelation(promise2,promise3,resolve,reject);
                }catch(e){
                    reject(e);
                }
            },0);
        }
        if(that.status === 'pending'){
            that.onFilFulledCallbacks.push(function(){
                /** 同2 */
                setTimeout(()=>{
                    try{
                        let promise3 = onFilfulled(that.value);
                        /** 同3*/
                        resolvePromiseRelation(promise2,promise3,resolve,reject);
                    }catch(e){
                        reject(e);
                    }
                },0);
            });
        }
        if(that.status === 'pending'){
            that.onRejectedCallbacks.push(function(){
                 /** 同2 */
                 setTimeout(()=>{
                    try{
                        let promise3 = onRejected(that.reason);
                        /** 同3*/
                        resolvePromiseRelation(promise2,promise3,resolve,reject);
                    }catch(e){
                        reject(e);
                    }
                },0);
            });
        }
    });
    /** 同1 */
    return promise2;
}

function resolvePromiseRelation(promise2,promise3,resolve,reject){
     /** 4 防备本身守候本身 一向轮回守候 */
    if(promise2 === promise3){
        return reject(new TypeError('轮回援用了!'));
    }
    /**  8 一个标示 示意当前没有被挪用过 
     *   确保resolve或许reject后的状况不会再次发作变动
    */ 
    let called;
     /** 5 保证promise3是一个援用范例
      *  推断新返回值promise3的范例 
      *  假如是一般值常量 就直接resolve导出 */
    if(promise3!==null&&(typeof promise3 === 'object'||typeof promise3 === 'function')){
        try{
            let then = promise3.then;
            /** 6 确保promise3是一个Promise
             *  推断promise3的then要领
             *  假如存在 而且是一个function范例 
             *  就示意promise3是一个Promise */
            if(typeof then === 'function'){
                /** 9 实行promise3的then要领
                 *  由于promise3也是一个Promise
                 *  须要再次剖析promise3的then要领
                 *  直到剖析到末了的返回值不是一个Promise范例为止
                 */
                then(promise3, (promise4)=>{
                    /** 同8 */
                    if(called) return;
                    called = true;
                    /** 10 递归剖析新的返回值的范例
                     *  剖析到返回值不是一个Promise范例为止
                     */
                    resolvePromiseRelation(promise3,promise4,resolve,reject);
                },(r)=>{
                    /** 同8 */
                    if(called) return;
                    called = true;
                    reject(r);
                });
            }else{
                /** 7 此时promise3是一个一般对象 直接resolve() */
                resolve(promise3);
            }
        }catch(e){
            /** 同8 */
            if(called) return;
            called = true;
            reject(e);
        };
    }else{
        /** 同5 一般值直接resolve()*/
        resolve(promise3);
    }
}

module.exports = Promise;

ok. 至此 我们已完成了Promsie的异步和链式挪用. Promise中比较庞杂的部份我们已搞定了 接下来就是增加一些要领,实在这部份反而没那末庞杂了.

catch : catch要领本质上就是一个then要领的变形,只要失利时的回调 没有胜利时的回调
finally : finally要领的作用是不论 Promise 对象末了状况怎样,都邑实行操纵.实在说白了就是在then要领的胜利和失利的回调函数中都实行该要领就好了.

ok.老例子 上代码~

增添catch finally要领



function Promise(executor){
    let that = this;
    that.status = 'pending';
    that.value = null;
    that.reason = null;
    that.onFilFulledCallbacks = [];
    that.onRejectedCallbacks = [];

    function resolve(value){
        if(that.status === 'pending'){
            that.status = 'resolved';
            that.value = value;
            that.onFilFulledCallbacks.forEach((fn)=>{
                fn();
            });
        }
    }
    function reject(reason){
        if(that.status === 'pending'){
            that.status = 'rejected';
            that.reason = reason;
            that.onRejectedCallbacks.forEach((fn)=>{
                fn();
            });
        }
    }
    executor(resolve,reject);
}

Promise.prototype.then = function(onFilfulled,onRejected){
    /** 2 此处有个坑 假如只写1 不写2的话
     *  会报一个TypeError :onRejected is not a function
     *  在此处给它一个默许的胜利和失利的回调函数就好 */
    onFilfulled = typeof onFilfulled === 'function'?onFilfulled:value=>value;
    onRejected = typeof onRejected ===  'function'?onRejected:err=>{throw err};
    let that = this;
    let promise2 = new Promise((resolve,reject)=>{
        if(that.status === 'resolved'){
            setTimeout(()=>{
                try{
                    let promise3 = onFilfulled(that.value);
                    resolvePromiseRelation(promise2,promise3,resolve,reject);
                }catch(e){
                    reject(e);
                }
            },0);
        }
        if(that.status === 'rejected'){
            setTimeout(()=>{
                try{
                    let promise3 = onRejected(that.reason);
                    resolvePromiseRelation(promise2,promise3,resolve,reject);
                }catch(e){
                    reject(e);
                }
            },0);
        }
        if(that.status === 'pending'){
            that.onFilFulledCallbacks.push(function(){
                setTimeout(()=>{
                    try{
                        let promise3 = onFilfulled(that.value);
                        resolvePromiseRelation(promise2,promise3,resolve,reject);
                    }catch(e){
                        reject(e);
                    }
                },0);
            });
        }
        if(that.status === 'pending'){
            that.onRejectedCallbacks.push(function(){
                 setTimeout(()=>{
                    try{
                        let promise3 = onRejected(that.reason);
                        resolvePromiseRelation(promise2,promise3,resolve,reject);
                    }catch(e){
                        reject(e);
                    }
                },0);
            });
        }
    });
    return promise2;
}

function resolvePromiseRelation(promise2,promise3,resolve,reject){
    if(promise2 === promise3){
        return reject(new TypeError('轮回援用了!'));
    }
    let called;
    if(promise3!==null&&(typeof promise3 === 'object'||typeof promise3 === 'function')){
        try{
            let then = promise3.then;
            if(typeof then === 'function'){
                then(promise3, (promise4)=>{
                    if(called) return;
                    called = true;
                    resolvePromiseRelation(promise3,promise4,resolve,reject);
                },(r)=>{
                    if(called) return;
                    called = true;
                    reject(r);
                });
            }else{
                resolve(promise3);
            }
        }catch(e){
            if(called) return;
            called = true;
            reject(e);
        };
    }else{
        resolve(promise3);
    }
}

/** 1 直接返回this的then要领
 *  由于catch只捕捉毛病 所以resolve直接为null
 *  返回reject就好*/
Promise.prototype.catch = function(errFn){
    return this.then(null,errFn);
}

/** 3 finally完成起来也很简朴 
 *  分别在resolve和reject中实行fn就好 
 *  末了再把this返回出去就好
*/
Promise.prototype.finally = function(fn){
    this.then(()=>{
        fn();
    },()=>{
        fn();
    });
    return this;
}

module.exports = Promise;

增添all race resolve reject等要领



function Promise(executor){
    let that = this;
    that.status = 'pending';
    that.value = null;
    that.reason = null;
    that.onFilFulledCallbacks = [];
    that.onRejectedCallbacks = [];

    function resolve(value){
        if(that.status === 'pending'){
            that.status = 'resolved';
            that.value = value;
            that.onFilFulledCallbacks.forEach((fn)=>{
                fn();
            });
        }
    }
    function reject(reason){
        if(that.status === 'pending'){
            that.status = 'rejected';
            that.reason = reason;
            that.onRejectedCallbacks.forEach((fn)=>{
                fn();
            });
        }
    }
    executor(resolve,reject);
}

Promise.prototype.then = function(onFilfulled,onRejected){
    onFilfulled = typeof onFilfulled === 'function'?onFilfulled:value=>value;
    onRejected = typeof onRejected ===  'function'?onRejected:err=>{throw err};
    let that = this;
    let promise2 = new Promise((resolve,reject)=>{
        if(that.status === 'resolved'){
            setTimeout(()=>{
                try{
                    let promise3 = onFilfulled(that.value);
                    resolvePromiseRelation(promise2,promise3,resolve,reject);
                }catch(e){
                    reject(e);
                }
            },0);
        }
        if(that.status === 'rejected'){
            setTimeout(()=>{
                try{
                    let promise3 = onRejected(that.reason);
                    resolvePromiseRelation(promise2,promise3,resolve,reject);
                }catch(e){
                    reject(e);
                }
            },0);
        }
        if(that.status === 'pending'){
            that.onFilFulledCallbacks.push(function(){
                setTimeout(()=>{
                    try{
                        let promise3 = onFilfulled(that.value);
                        resolvePromiseRelation(promise2,promise3,resolve,reject);
                    }catch(e){
                        reject(e);
                    }
                },0);
            });
        }
        if(that.status === 'pending'){
            that.onRejectedCallbacks.push(function(){
                 setTimeout(()=>{
                    try{
                        let promise3 = onRejected(that.reason);
                        resolvePromiseRelation(promise2,promise3,resolve,reject);
                    }catch(e){
                        reject(e);
                    }
                },0);
            });
        }
    });
    return promise2;
}

function resolvePromiseRelation(promise2,promise3,resolve,reject){
    if(promise2 === promise3){
        return reject(new TypeError('轮回援用了!'));
    }
    let called;
    if(promise3!==null&&(typeof promise3 === 'object'||typeof promise3 === 'function')){
        try{
            let then = promise3.then;
            if(typeof then === 'function'){
                then(promise3, (promise4)=>{
                    if(called) return;
                    called = true;
                    resolvePromiseRelation(promise3,promise4,resolve,reject);
                },(r)=>{
                    if(called) return;
                    called = true;
                    reject(r);
                });
            }else{
                resolve(promise3);
            }
        }catch(e){
            if(called) return;
            called = true;
            reject(e);
        };
    }else{
        resolve(promise3);
    }
}

Promise.prototype.catch = function(errFn){
    return this.then(null,errFn);
}
Promise.prototype.finally = function(fn){
    this.then(()=>{
        fn();
    },()=>{
        fn();
    });
    return this;
}

/** 1 直接在组织函数上增添all要领
 *  它返回的也是一个Promise
 *  守候参数数组中一切的promise都实行终了后
 *  再返回效果
 */
Promise.all = function(values){
    return new Promise((resolve,reject)=>{
        /** 2 定义一个寄存终究效果的数组result和一个index */ 
        let results = [];
        let index = 0;
        /** 3 定义一个要领addToArr()  
         *  让index每次实行增添results数组元素的函数的时刻都+1
         *  当index === values的长度的时刻 申明此时一切promsie都实行终了并放到的数组中
         *  然后直接resolve(results)就好了
        */
        function addToArr(key,value){
            index++;
            results[key] = value;
            /** 6 当满足前提时 申明一切的promise都实行终了 直接resolve(results) */
            if(index === values.length){
                resolve(results);
            }
        }
        /** 4 轮回values中的每一项promsie */
        for(let i = 0; i < values.length; i++){
            let current = values[i];
            /** 5 推断每一项promise的返回值是不是是一个Promsie
             *  是的话就实行该Promise的then要领 拿到返回值 并放到数组results中
             *  是一个一般值的话就直接将该值放到数组results中
             */
            if(current && current.then && typeof current.then === 'function'){
                current.then((value)=>{
                    /** 同5 把返回值放到数组results中*/
                    addToArr(i,value);
                },reject);
            }else{
                /** 同5 把返回值放到数组results中*/
                addToArr(i,current);
            }
        }
    });
}

/** race要领相比较于all要领简朴许多
 *  由于race中的promsie胜利resolve一个 
 *  全部race就resolve */
Promise.race = function(values){
    return new Promise((resolve,reject)=>{
        /** 同4 */
        for(let i = 0; i < values.length; i++){
            let current = values[i];
            /** 同5 */
            if(current&&current.then&&typeof current.then === 'function'){
                /** 7 直接实行then就好 */
                current.then(resolve,reject);
            }else{
                /** 8 一般值直接resolve */
                resolve(current);
            }
        }
    });
}

// resolve要领
Promise.resolve = function(value){
    return new Promise((resolve,reject)=>{
        resolve(value);
    });
}
// reject要领
Promise.reject = function(reason){
    return new Promise((resolve,reject)=>{
        reject(reason);
    });
}

module.exports = Promise;

完成一个promise的耽误对象defer

此步是为了测试我们手写的Promsie符不相符Promsie/A+范例,假如没有defer的话,我们在测试历程中就会报一个TypeError: adapter.deferred is not a function.

实在写完defer后,我们就能够去举行测试我们手写的Promsie符不相符Promsie/A+范例了。

即:本篇手写一款相符Promise/A+范例的Promise的终究本为:



function Promise(executor){
    let that = this;
    that.status = 'pending';
    that.value = null;
    that.reason = null;
    that.onFilFulledCallbacks = [];
    that.onRejectedCallbacks = [];

    function resolve(value){
        if(that.status === 'pending'){
            that.status = 'resolved';
            that.value = value;
            that.onFilFulledCallbacks.forEach((fn)=>{
                fn();
            });
        }
    }
    function reject(reason){
        if(that.status === 'pending'){
            that.status = 'rejected';
            that.reason = reason;
            that.onRejectedCallbacks.forEach((fn)=>{
                fn();
            });
        }
    }
    try{
        executor(resolve,reject);
    }catch(e){
        reject(e);
    }
}

Promise.prototype.then = function(onFilfulled,onRejected){
    onFilfulled = typeof onFilfulled === 'function'?onFilfulled:value=>value;
    onRejected = typeof onRejected === 'function'?onRejected:err=>{throw err};
    let that = this;
    let promise2 = new Promise((resolve,reject)=>{
        if(that.status === 'resolved'){
            setTimeout(()=>{
                try{
                    let promise3 = onFilfulled(that.value);
                    resolvePromiseRelation(promise2,promise3,resolve,reject);
                }catch(e){
                    reject(e);
                }
            },0);
        }
        if(that.status === 'rejected'){
            setTimeout(()=>{
                try{
                    let promise3 = onRejected(that.reason);
                    resolvePromiseRelation(promise2,promise3,resolve,reject);
                }catch(e){
                    reject(e);
                }
            },0);
        }
        if(that.status === 'pending'){
            that.onFilFulledCallbacks.push(function(){
                setTimeout(()=>{
                    try{
                        let promise3 = onFilfulled(that.value);
                        resolvePromiseRelation(promise2,promise3,resolve,reject);
                    }catch(e){
                        reject(e);
                    }
                },0);
            });
            that.onRejectedCallbacks.push(function(){
                setTimeout(()=>{
                   try{
                       let promise3 = onRejected(that.reason);
                       resolvePromiseRelation(promise2,promise3,resolve,reject);
                   }catch(e){
                       reject(e);
                   }
               },0);
           });
        }
    });
    return promise2;
}

function resolvePromiseRelation(promise2,promise3,resolve,reject){
    if(promise2 == promise3){
        return reject(new TypeError('轮回援用了!'));
    }
    let called;
    if(promise3!==null&&(typeof promise3 === 'object' || typeof promise3 === 'function')){
        try{
            let then = promise3.then;
            if(typeof then === 'function'){
                then.call(promise3, (promise4)=>{
                    if(called) return;
                    called = true;
                    resolvePromiseRelation(promise3,promise4,resolve,reject);
                },(r)=>{
                    if(called) return;
                    called = true;
                    reject(r);
                });
            }else{
                resolve(promise3);
            }
        }catch(e){
            if(called) return;
            called = true;
            reject(e);
        };
    }else{
        resolve(promise3);
    }
}

Promise.prototype.catch = function(errFn){
    return this.then(null,errFn);
}
Promise.prototype.finally = function(fn){
    this.then(()=>{
        fn();
    },()=>{
        fn();
    });
    return this;
}

Promise.all = function(values){
    return new Promise((resolve,reject)=>{
        let results = [];
        let index = 0;
        function addToArr(key,value){
            index++;
            results[key] = value;
            if(index === values.length){
                resolve(results);
            }
        }
        for(let i = 0; i < values.length; i++){
            let current = values[i];
            if(current && current.then && typeof current.then === 'function'){
                current.then((value)=>{
                    addToArr(i,value);
                },reject);
            }else{
                addToArr(i,current);
            }
        }
    });
}

Promise.race = function(values){
    return new Promise((resolve,reject)=>{
        for(let i = 0; i < values.length; i++){
            let current = values[i];
            if(current&&current.then&&typeof current.then === 'function'){
                current.then(resolve,reject);
            }else{
                resolve(current);
            }
        }
    });
}

Promise.resolve = function(value){
    return new Promise((resolve,reject)=>{
        resolve(value);
    });
}

Promise.reject = function(reason){
    return new Promise((resolve,reject)=>{
        reject(reason);
    });
}
// 完成一个promise的耽误对象 defer
Promise.defer = Promise.deferred = function(){
    let dfd = {};
    dfd.promise = new Promise((resolve, reject)=>{
        dfd.resolve = resolve;
        dfd.reject = reject;
    });
    return dfd;
}
module.exports = Promise;

终究测试

  • 测试当前代码是不是相符Promise/A+范例
  • 全局装置 npm i -g promises-aplus-tests
  • 文件地点目次运转以下敕令 (比方你的文件名为:MyPrommise.js)
  • promise-aplus-tests MyPrommise.js
  • 守候
  • ok.

《手写一款相符Promise/A+范例的Promise》

源码在github上,写文章不容易,迎接star或fork,thx~
github

    原文作者:Funky_Tiger
    原文地址: https://segmentfault.com/a/1190000018209663
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞