天天看點

自我實作promise

ps:代碼是抄的,不知道抄的那位大哥的,介意,聯系我删除哈

function Promise(fn) {

var data = undefined,

reason = undefined;

var succallbacks = [];

var failcallbacks = []; //失敗隊列

var status = “pending”; //狀态等待

this.then = function(fulfilled, rejected) { //Promise的.then 傳進兩個參數,第一個是失敗的隊列,第二個成功傳回的reject

return new Promise(function(resolve, reject) { //傳回一個新的promise return一個新的prominse,可以進行.then的鍊式 傳回的promise裡面有新的fn

function suc(value) { //成功

var ret = typeof fulfilled === ‘function’ && fulfilled(value) || value;

if (ret && typeof ret[‘then’] == ‘function’) { //判斷 then中的 傳回的是否是promise對象,如果是注冊then方法

ret.then(function(value) {

resolve(value);

});

} else {

resolve(ret);

}

}

function errback(reason) { //失敗
                    reason = typeof rejected === 'function' && rejected(reason) || reason;
                    reject(reason);
                }

                if (status === 'pending') {
                    succallbacks.push(suc);
                    failcallbacks.push(errback);
                } else if (status === 'fulfilled') {
                    suc(data);
                } else {
                    errback(reason);
                }
            })

        }

        function resolve(value) {
            setTimeout(function() { //加入延時
                status = "fulfilled";
                data = value;
                succallbacks.forEach((callback) => {
                    callback(value);
                })
            }, 0)

        }

        function reject(value) {
            setTimeout(function() {
                status = "rejected";
                reason = value;
                failcallbacks.forEach((callback) => {
                    callback(value);
                })

            }, 0)
        }

        fn(resolve, reject);
    }

    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(1);
        }, 1000)
    });

    p.then(data => {
        console.log(data);
        return new Promise((resolve, reject) => { //then 方法傳回的是一個promise對象,故執行 promise中的then注冊該結果,在resolve
            setTimeout(() => {
                resolve(2);
            }, 1000)
        })
    }).then(data => {
        console.log(data);
    })