es6 promise源碼實現

promise源碼分析

初級入門以及如何使用請看 阮一峯promise對象講解

先上一坨代碼,後面咱們要基於這坨代碼來實現自定義promise

原始方法

setTimeout(function(){
    var a=100;
    console.log(a);
    setTimeout(function () {
        var b=200;
        console.log(b)
        setTimeout(function () {
            var c=300;
            console.log(c)
        }, 1000);
    }, 1000);
},1000);

promise實現

new Promise(function (resolve, reject) {
    setTimeout(function () {
        var a=100;
        resolve(a);
    }, 1000);
}).then(function (res) {
    console.log(res);
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            var b=200;
            resolve(b);
        }, 1000);
    })
}).then(function (res) {
    console.log(res);
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            var c=300
            resolve(c);
        }, 1000);
    })
}).then(function (res) {
        console.log(res);
    }
    )

如何讓你的promise能有此魔力

  • 讓a,b,c的值能在then裏面的回調接收到
  • 在連續調用異步,如何確保異步函數的執行順序

如何讓異步的value在thenable函數中拿到

  • 將resolve/reject函數和onfulfiled/onrejected放入同一個對象(promise對象)裏面,resolve/reject的時候將value設置this.value=xxx。onfulfiled/onrejected執行的時候呢,onfulfiled(this.value)便可

如何處理鏈式的promise且保證順序

  • 每一個promise後面鏈一個對象該對象包含onfulfiled,onfulfiled,子promise三個屬性.

當父promise 狀態改變完畢,執行完相應的onfulfiled/onfulfiled的時候呢,拿到子promise,在等待這個子promise狀態改變,在執行相應的onfulfiled/onfulfiled。依次循環直到當前promise沒有子promisegit

最終代碼(內涵註釋)

/*
            咱們要知足狀態只能三種狀態:PENDING,FULFILLED,REJECTED三種狀態,且狀態只能由PENDING=>FULFILLED,或者PENDING=>REJECTED
            */
            var PENDING = 0;
            var FULFILLED = 1;
            var REJECTED = 2;
            /*
            value狀態爲執行成功事件的入參,deferreds保存着狀態改變以後的須要處理的函數以及promise子節點,構造函數裏面應該包含這三個屬性的初始化
             */
            function Promise(callback) {
                this.status = PENDING;
                this.value = null;
                this.defferd = [];
                setTimeout(callback.bind(this, this.resolve.bind(this), this.reject.bind(this)), 0);
            }
            
            Promise.prototype = {
                constructor: Promise,
                //觸發改變promise狀態到FULFILLED
                resolve: function (result) {
                    this.status = FULFILLED;
                    this.value = result;
                    this.done();
                },
                //觸發改變promise狀態到REJECTED
                reject: function (error) {
                    this.status = REJECTED;
                    this.value = error;
                },
                //處理defferd
                handle: function (fn) {
                    if (!fn) {
                        return;
                    }
                    var value = this.value;
                    var t = this.status;
                    var p;
                    if (t == PENDING) {
                         this.defferd.push(fn);
                    } else {
                        if (t == FULFILLED && typeof fn.onfulfiled == 'function') {
                            p = fn.onfulfiled(value);
                        }
                        if (t == REJECTED && typeof fn.onrejected == 'function') {
                            p = fn.onrejected(value);
                        }
                    var promise = fn.promise;
                    if (promise) {
                        if (p && p.constructor == Promise) {
                            p.defferd = promise.defferd;
                        } else {
                            p = this;
                            p.defferd = promise.defferd;
                            this.done();
                        }
                    }
                    }
                },
                //觸發promise defferd裏面須要執行的函數
                done: function () {
                    var status = this.status;
                    if (status == PENDING) {
                        return;
                    }
                    var defferd = this.defferd;
                    for (var i = 0; i < defferd.length; i++) {
                        this.handle(defferd[i]);
                    }
                },
                /*儲存then函數裏面的事件
                返回promise對象
                defferd函數當前promise對象裏面
                */
                then: function (success, fail) {
                   var o = {
                        onfulfiled: success,
                        onrejected: fail
                    };
                    var status = this.status;
                    o.promise = new this.constructor(function () {
            
                    });
                    if (status == PENDING) {
                        this.defferd.push(o);
                    } else if (status == FULFILLED || status == REJECTED) {
                        this.handle(o);
                    }
                    return o.promise;
                }
            };

在附上一張手繪的流程圖

圖片描述

參考資料

源碼地址

相關文章
相關標籤/搜索