小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Promise的源碼實現(xiàn)(符合Promise/A 規(guī)范)

 印度阿三17 2019-07-09

我們手寫一個Promise/A 規(guī)范,然后安裝測試腳本,以求通過這個規(guī)范。

//Promise/A 源代碼
// new Promise時,需要傳遞一個executor執(zhí)行器,執(zhí)行器立即執(zhí)行
// executor接受兩個參數(shù),分別是resolve和reject
// promise只能從pending到rejected,或者從pending到fulfilled
// promise的狀態(tài)一旦確認(rèn),就不會再改變
// promise有then方法,then接受兩個參數(shù),分別是promise成功的回調(diào)onFulfilled
// 和promise失敗的回調(diào) onRejected
// 如果調(diào)用then時,promise已經(jīng)成功,則執(zhí)行onFulfilled,并將promise值作為參數(shù)傳遞進去
// 如果promise已經(jīng)失敗,那么執(zhí)行onRejected并把promise失敗的原因作為參數(shù)傳遞進去
// 如果promise狀態(tài)是pending,需要將onFulfilled和onRejected函數(shù)存放起來,等待狀態(tài)確定后,再一次將對應(yīng)的函數(shù)執(zhí)行(發(fā)布)
// then的參數(shù)onFulfilled和onRejected可以缺省
// promise可以then多次,promise的then方法返回一個promise
// 如果then返回的是一個結(jié)果,那么就把這個結(jié)果作為參數(shù),傳遞給下一個then的成功的回調(diào)onFulfilled
// 如果then中拋出了異常,那么就會把這個異常作為參數(shù),傳遞給下一個失敗的回調(diào) onRejected
// 如果then返回的是一個promise,那么需要等這個promise,那么會等這個promise執(zhí)行完,promise如果成功
// 就走下一個then的成功,如果失敗,就走下一個then的失敗
//pending狀態(tài),可以認(rèn)為是一種中間狀態(tài)
const PENDING = 'pending';
// fullfilled完成狀態(tài),可以認(rèn)為是成功回調(diào)了的狀態(tài)
const FULFILLED = 'fullfilled';
// reject即為拒絕狀態(tài),即失敗的狀態(tài)
const REJECTED = 'reject';
// executor是一個執(zhí)行器
function Promise(executor){
    let self = this;
    self.status = PENDING;
    self.onFulfilled = [];//成功的回調(diào)
    self.onRejected = [];//失敗的回調(diào)
    // PromiseA  2.1
    function resolve(value){
        if(self.status === PENDING){
            self.status = FULFILLED;
            self.value = value;
            self.onFulfilled.forEach(fn=>fn());//PromiseA  2.2.6.1
        }
    }
    function reject(reason){
        if(self.status===PENDING){
            self.status = REJECTED;
            self.reason = reason;
            self.onRejected.forEach(fn=>fn());//PromiseA  2.2.6.2
        }
    }
    try{
        executor(resolve,reject)
    }catch(e){
        reject(e)
    }
}
// then必須返回一個promise
Promise.prototype.then = function(onFulfilled,onRejected){
    // PromiseA  2.2.1/PromiseA  2.2.5/PromiseA  2.2.7.3/PromiseA 2.2.7.4
    onFulfilled = typeof onFulfilled ==='function'?onFulfilled:value =>value;
    onRejected = typeof onRejected === 'function'?onRejected:reason=>{throw reason};
    let self = this;
    //PromiseA  2.2.7
    let Promise2 = new Promise((resolve,reject)=>{
        if(self.status===FULFILLED){
            //PromiseA 2.2.2
            // Promise A 2.2.4----setTimeout
            setTimeout(()=>{
                try{
                    let x = onFulfilled(self.value);
                    resolvePromise(promise2,x,resolve,reject);
                }catch(e){
                    //PromiseA 2.2.7.2
                    reject(e)
                }
            });
        }else if(self.status === REJECTED){
            // PromiseA  2.2.3
            setTimeout(()=>{
                try{
                    let x = onRejected(self.reason);
                    resolvePromise(promise2,x,resolve,reject);
                }catch(e){
                    reject(e);
                }
            })
        }else if(self.status===PENDING){
            self.onFulfilled.push(()=>{
                setTimeout(()=>{
                    try{
                        let x = onFulfilled(self.value);
                        resolvePromise(promise2,x,resolve,reject);
                    }catch(e){
                        reject(e);
                    }
                });
            });
        }
    });
    return promise2;
}
function resolvePromise(promise2,x,resolve,reject){
    let self = this;
    //PromiseA  2.3.1
    if(promise2===x){
        reject(new TypeError('changing cycle'));
    }
    if(x && typeof x ==="object"|| typeof x ==='function'){
        let used;//PromiseA  2.3.3.3.3//只能調(diào)用一次
        try{
            let then = x.then;
            if(typeof then === 'function'){
                //PromiseA 2.3.3
                then.call(x,(y)=>{
                    // PromiseA  2.3.3.1
                    if(used)return;
                    used = true;
                    resolvePromise(promise2,y,resolve,reject);
                },(r)=>{
                    //PromiseA 2.3.3.2
                    if(used)return;
                    used = true;
                    reject(r)
                });
            }else{
                //PromiseA  2.3.3.4
                if(used)return;
                used = true;
                reject(x);
            }
        }catch(e){
            //PromiseA  2.3.3.2
            if(used)return;
            used = true;
            reject(e);
        }
    }else{
        //PromiseA  2.3.3.4
        resolve(x);
    }
}
module.exports = Promise;

我們可以用專門的測試腳本測試所編寫的代碼是否符合PromiseA 的規(guī)范。
在上面的promise實現(xiàn)的代碼中,增加一下代碼

Promise.defer = Promise.deferred = function(){
    let dfd = {};
    dfd.promise = new Promise((resolve,reject)=>{
        dfd.resolve = resolve;
        dfd.reject = reject;
    });
    return dfd;
}

安裝測試腳本

npm install -g promises-aplus-tests

如果當(dāng)前的promise源碼的文件名為promise.js

那么在對應(yīng)的目錄執(zhí)行以下命令:

promises-aplus-tests promise.js

promises-aplus-tests中共有872條測試用例。以上代碼,可以完美通過所有用例。

本文借鑒自:https://blog.csdn.net/liuyan19891230/article/details/88385973

來源:https://www./content-1-311801.html

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多