本身照着Promise/A規範寫的Promise庫

試圖寫了一下,大概測試了一下,沒有用專業的測試工具測試....git

代碼感受仍是寫的比較好懂的,本人水平較差,若是測試有問題,歡迎回復指出
地址: https://github.com/julyL/Code...github

(function(global) {
    function isFunction(val) {
        return typeof val == 'function';
    }

    function isObject(val) {
        return typeof val == 'object';
    }

    function asyncExcute(fn) {
        return function() {
            setTimeout(fn); // 同一執行隊列中,原生Promise是先於setTimeout實現的,本身實現暫時用setTimeout模擬
        }
    }
    function Promise(fn) {
        if (!isFunction(fn) || this instanceof Promise == false) {
            throw new TypeError("Promise必須傳入function而且new構造")
        }
        this.status = 'pending';
        this.value = undefined; //  promise狀態改變以後傳遞的值
        this.thenPromise = undefined; //執行then以後返回的promise
        this.resolveQueue = []; //
        this.rejectQueue = []; //   
        var re = asyncExcute(function(resolveData) { this._resolve(resolveData) }.bind(this)), //這裏必須異步處理,不然then函數執行之前可能就已經執行了_resolve,但這時then中函數還未加入resolveQueue中
            rj = asyncExcute(function(resolveData) { this._reject(resolveData) }.bind(this));
        try {
            fn(re, rj)
        } catch (error) {
            this.status = 'reject';
            this.value = error;
            asyncExcute(function(){this._reject(error)});         //  new Promise(()=>{ 出現異常... }).then(refn,rjfn);    出現異常時then還未執行, rjfn還未加入到rejectQueue中  
        }
    }
    Promise.prototype.then = function(refn, rjfn) {
        var returnPro = new Promise(function() {});
        this.thenPromise = returnPro;
        this.resolveQueue.push(refn);
        this.rejectQueue.push(rjfn);

        if (this.status == 'resolve') { //執行then時,若是狀態已經不是pending,則執行相應函數
            this._resolve(this.value);
        }
        if (this.status == 'reject') {
            this._reject(this.value);
        }
        return returnPro;
    }
    Promise.prototype._resolve = function(resolveData) {
        var handle,
            returnVal;
        this.status = "resolve";
        this.value = resolveData;
        while (this.resolveQueue.length > 0) { //2.2.6  當 promise 成功執行時,全部 onFulfilled 需按照其註冊順序依次回調
            handle = this.resolveQueue.shift();
            if (!isFunction(handle)) { //不是函數  2.1.1 onFulfilled 不是函數,其必須被忽略
                this.thenPromise.value = resolveData;
                this.thenPromise.status = 'resolve';
                this.thenPromise._resolve();
                return;
            }
            try { //若是 onFulfilled 或者 onRejected 拋出一個異常 e ,則 promise2 必須拒絕執行,並返回拒因 e
                returnVal = handle(resolveData);
            } catch (error) {
                this.thenPromise.status = 'reject';
                this.thenPromise.value = error;
                this.thenPromise._reject();
            }
            if (isObject(returnVal || isFunction(returnVal))) { //若是返回值爲對象或者函數
                if (returnVal == this.thenPromise) { //若是 promise 和 x 指向同一對象,以 TypeError 爲據因拒絕執行 promise
                    this.thenPromise.status = 'reject';
                    this.thenPromise.value = new TypeError('[[Resolve]](promise, x),promise 和 x 不能指向同一對象');
                } else if (returnVal instanceof Promise) { //若是 x 爲 Promise ,則使 promise 接受 x 的狀態
                    try {
                        then.call(returnVal, this.thenPromise._resolve.bind(this.thenPromise), this.thenPromise._reject.bind(this.thenPromise));
                    } catch (error) {
                        this.thenPromise.status = 'reject';
                        this.thenPromise.value = error;
                        this.thenPromise._reject();
                    }
                } else { //若是 x 爲對象或者函數
                    try { //若是取 x.then 的值時拋出錯誤 e ,則以 e 爲據因拒絕 promise
                        var then = returnVal.then;
                        if (isFunction(then)) {
                            then.call(returnVal, this.thenPromise._resolve.bind(this.thenPromise), this.thenPromise._reject.bind(this.thenPromise));
                        }
                    } catch (error) {
                        this.thenPromise.status = 'reject';
                        this.thenPromise.value = error;
                        this.thenPromise._reject();
                    }
                }
            } else {
                this.thenPromise.value = returnVal;
                this.thenPromise.status = 'resolve';
                this.thenPromise._resolve();
            }
        }
    }

    Promise.prototype._reject = function(resolveData) {
        var handle,
            returnVal;
        this.status = "resolve";
        this.value = resolveData;
        while (this.rejectQueue.length > 0) {     //2.2.6  當 promise 成功執行時,全部 onFulfilled 需按照其註冊順序依次回調
            handle = this.rejectQueue.shift();
            if (!isFunction(handle)) {          //不是函數  2.1.1 onFulfilled 不是函數,其必須被忽略
                this.thenPromise.value = resolveData;
                this.thenPromise.status = 'resolve';
                this.thenPromise._resolve();
                return;
            }
            try { //若是 onFulfilled 或者 onRejected 拋出一個異常 e ,則 promise2 必須拒絕執行,並返回拒因 e
                returnVal = handle(resolveData);
            } catch (error) {
                this.thenPromise.status = 'reject';
                this.thenPromise.value = error;
                this.thenPromise._reject();
            }
            if (isObject(returnVal || isFunction(returnVal))) { //若是返回值爲對象或者函數
                if (returnVal == this.thenPromise) { //若是 promise 和 x 指向同一對象,以 TypeError 爲據因拒絕執行 promise
                    this.thenPromise.status = 'reject';
                    this.thenPromise.value = new TypeError('[[Resolve]](promise, x),promise 和 x 不能指向同一對象');
                } else if (returnVal instanceof Promise) { //若是 x 爲 Promise ,則使 promise 接受 x 的狀態
                    try {
                        then.call(returnVal, this.thenPromise._resolve.bind(this.thenPromise), this.thenPromise._reject.bind(this.thenPromise));
                    } catch (error) {
                        this.thenPromise.status = 'reject';
                        this.thenPromise.value = error;
                        this.thenPromise._reject();
                    }
                } else {      //若是 x 爲對象或者函數
                    try {     //若是取 x.then 的值時拋出錯誤 e ,則以 e 爲據因拒絕 promise
                        var then = returnVal.then;
                        if (isFunction(then)) {
                            then.call(returnVal, this.thenPromise._resolve.bind(this.thenPromise), this.thenPromise._reject.bind(this.thenPromise));
                        }
                    } catch (error) {
                        this.thenPromise.status = 'reject';
                        this.thenPromise.value = error;
                        this.thenPromise._reject();
                    }
                }
            } else {
                this.thenPromise.value = returnVal;
                this.thenPromise.status = 'resolve';
                this.thenPromise._resolve();
            }
        }
    }

    Promise.resolve = function(value) {
        return new Promise(function(re, rj) {
            re(value)
        })
    }
    Promise.reject = function(value) {
        return new Promise(function(re, rj) {
            re(value)
        })
    }
    Promise.all = function(queue) {
        if (Object.prototype.toString.call(queue) != "[object Array]") {
            return;
        }
        var returnPromise = new Promise(function() {}),
            resolveNum = 0;
        for (var i = 0; i < queue.length; i++) {
            queue[i].then(function() {
                resolveNum++;
                if (resolveNum == queue.length) {
                    returnPromise._resolve();
                }
            });
        }
        return returnPromise;
    }
    Promise.race = function(queue) {
        if (Object.prototype.toString.call(queue) != "[object Array]") {
            return;
        }
        var returnPromise = new Promise(function() {}),
            resolveNum = 0;
        for (var i = 0; i < queue.length; i++) {
            queue[i].then(function() {
                returnPromise._resolve();
            });
        }
        return returnPromise;
    }
    global.Promise = Promise;
})(window);
相關文章
相關標籤/搜索