手寫實現promise

// 簡易版本的promise

    // 第一步: 列出三大塊  this.then   resolve/reject   fn(resolve,reject)
    // 第二步: this.then負責註冊所有的函數   resolve/reject負責執行所有的函數 
    // 第三步: 在resolve/reject裏面要加上setTimeout  防止還沒進行then註冊 就直接執行resolve了
    // 第四步: resolve/reject裏面要返回this  這樣就可以鏈式調用了
    // 第五步: 三個狀態的管理 pending fulfilled rejected
 
    // *****promise的鏈式調用 在then裏面return一個promise 這樣才能then裏面加上異步函數
    // 加上了catch
    function PromiseM(fn) {
        var value = null;
        var callbacks = [];
        //加入狀態 爲了解決在Promise異步操作成功之後調用的then註冊的回調不會執行的問題
        var state = 'pending';
        var _this = this;

        //註冊所有的回調函數
        this.then = function (fulfilled, rejected) {
            //如果想鏈式promise 那就要在這邊return一個new Promise
            return new PromiseM(function (resolv, rejec) {
                //異常處理
                try {
                    if (state == 'pending') {
                        callbacks.push(fulfilled);
                        //實現鏈式調用
                        return;
                    }
                    if (state == 'fulfilled') {
                        var data = fulfilled(value);
                        //爲了能讓兩個promise連接起來
                        resolv(data);
                        return;
                    }
                    if (state == 'rejected') {
                        var data = rejected(value);
                        //爲了能讓兩個promise連接起來
                        resolv(data);
                        return;
                    }
                } catch (e) {
                    _this.catch(e);
                }
            });
        }

        //執行所有的回調函數
        function resolve(valueNew) {
            value = valueNew;
            state = 'fulfilled';
            execute();
        }

        //執行所有的回調函數
        function reject(valueNew) {
            value = valueNew;
            state = 'rejected';
            execute();
        }

        function execute() {
            //加入延時機制 防止promise裏面有同步函數 導致resolve先執行 then還沒註冊上函數
            setTimeout(function () {
                callbacks.forEach(function (cb) {
                    value = cb(value);
                });
            }, 0);
        }

        this.catch = function (e) {
            console.log(JSON.stringify(e));
        }

        //經典 實現異步回調
        fn(resolve, reject);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章