40行js實現一個簡易Promise

最近面試有問到Promise的原理,以及實現的方法。因此本身動手實現了一個,發個文章記錄下。
簡單分析下,promise實例對象有兩個屬性,一個是status,一個是value。還有一個then方法。
status有3個狀態,pending,resolved,rejected。value就是then回調的時候傳的值。
下面是代碼git

/* 
  原生js模擬promise
*/
const PromisePolyfill = (() => {
    //狀態管理
    const promiseStatusSymbol = Symbol('PromiseStatus');
    const promiseValueSymbol = Symbol('PromiseValue');
    const STATUS = {
        PENDING: 'PENDING',
        FULFILLED: 'FULFILLED',
        REJECTED: 'REJECTED'
    };
    //resolve操做設置值和狀態
    function resolve() {
        this[promiseValueSymbol] = arguments[0];
        this[promiseStatusSymbol] = STATUS['FULFILLED'];
    }
    //reject操做設置值和狀態
    function reject() {
        this[promiseValueSymbol] = arguments[0];
        this[promiseStatusSymbol] = STATUS['REJECTED'];
    }

    class myPromise {
        constructor(resolver) {
            if (typeof resolver !== 'function') {
                throw new TypeError(`parameter 1 must be a function, but get a ${typeof func}`);
            }
            this[promiseStatusSymbol] = STATUS['PENDING'];//初始狀態爲pending
            resolver(
                resolve.bind(this),//綁定promise實例對象
                reject.bind(this)
            );
        }
        then(callback) {
            //開一個定時器監聽狀態變化,若是有變化則執行callback
            const interval = setInterval(() => {
                if (this[promiseStatusSymbol] === 'FULFILLED' || this[promiseStatusSymbol] === 'REJECTED') {
                    clearInterval(interval);
                    callback(this[promiseValueSymbol], resolve.bind(this), reject.bind(this));
                    this[promiseStatusSymbol] = 'PENDING';//執行完後把狀態改回,方便下一個then方法進行定時輪詢
                }
            });
            return this;
        }
    }
    return myPromise;
})();

寫完了丟到控制檯測試,完美預期運行github

//測試,下面會先打印出111,再打印出222,333
new PromisePolyfill(function (resolve, reject) {
    setTimeout(() => {
        resolve(222);
        console.log(111)
    }, 1000);
}).then(function (res, resolve, reject) {
    setTimeout(() => {
        resolve(333);
        console.log(res)
    }, 3000);
}).then(function (res, resolve, reject) {
    console.log(res);
});

代碼github地址:https://github.com/leeseean/P...面試

相關文章
相關標籤/搜索