成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

異步發(fā)展流程 —— 手寫一個符合 Promise/A+ 規(guī)范的 Promise

UnixAgain / 2391人閱讀

摘要:構造函數(shù)的實現(xiàn)我們在使用的時候其實是使用關鍵字創(chuàng)建了一個的實例,其實是一個類,即構造函數(shù),下面來實現(xiàn)構造函數(shù)。


閱讀原文


概述

Promise 是 js 異步編程的一種解決方案,避免了 “回調(diào)地獄” 給編程帶來的麻煩,在 ES6 中成為了標準,這篇文章重點不是敘述 Promise 的基本用法,而是從零開始,手寫一版符合 Promise/A+ 規(guī)范的 Promise,如果想了解更多 Promise 的基本用法,可以看 異步發(fā)展流程 —— Promise 的基本使用 這篇文章。


Promise 構造函數(shù)的實現(xiàn)

我們在使用 Promise 的時候其實是使用 new 關鍵字創(chuàng)建了一個 Promise 的實例,其實 Promise 是一個類,即構造函數(shù),下面來實現(xiàn) Promise 構造函數(shù)。

Promise/A+ 規(guī)范的內(nèi)容比較多,詳情查看 https://promisesaplus.com/,我們在實現(xiàn) Promise 邏輯時會根據(jù)實現(xiàn)的部分介紹相關的 Promise/A+ 規(guī)范內(nèi)容。

在 Promise/A+ 規(guī)范中規(guī)定:

構造函數(shù)的參數(shù)為一個名為 executor 的執(zhí)行器,即函數(shù),在創(chuàng)建實例時該函數(shù)內(nèi)部邏輯為同步,即立即執(zhí)行;

executor 執(zhí)行時的參數(shù)分別為 resolvereject,一個為成功時執(zhí)行的函數(shù),一個為失敗時執(zhí)行的函數(shù);

executor 執(zhí)行時,一旦出現(xiàn)錯誤立即調(diào)用 reject 函數(shù),并設置錯誤信息給 reason 屬性;

每個 Promise 實例有三個狀態(tài) pendingfulfilledrejected,默認狀態(tài)為 pending;

狀態(tài)只能從 pendingfulfilled 或從 pendingrejected,且不可逆;

執(zhí)行 resolve 函數(shù)會使狀態(tài)從 pending 變化到 fulfilled 并將參數(shù)存入實例的 value 屬性中;

執(zhí)行 reject 函數(shù)會使狀態(tài)從 pending 變化到 rejected 并將錯誤信息存入實例的 reason 屬性中。

針對上面的 Promise/A+ 規(guī)范,Promise 構造函數(shù)代碼實現(xiàn)如下:

// promise.js -- Promise 構造函數(shù)
function Promise(executor) {
    var self = this;
    self.status = "pending"; // 當前 Promise 實例的狀態(tài)
    self.value = undefined; // 當前 Promise 實例成功狀態(tài)下的值
    self.reason = undefined; // 當前 Promise 實例失敗狀態(tài)的錯誤信息
    self.onFulfilledCallbacks = []; // 存儲成功的回調(diào)函數(shù)的數(shù)組
    self.onRejectedCallbacks = []; // 存儲失敗的回調(diào)函數(shù)的數(shù)組

    // 成功的執(zhí)行的函數(shù)
    function resolve(value) {
        if (self.status === "pending") {
            self.status = "fulfilled";
            self.value = value;
            // 每次調(diào)用 resolve 時,執(zhí)行 onFulfilledCallbacks 內(nèi)部存儲的所有的函數(shù)(在實現(xiàn) then 方法中詳細說明)
            self.onFulfilledCallbacks.forEach(function(fn) {
                fn();
            });
        }
    }

    // 失敗執(zhí)行的函數(shù)
    function reject(reason) {
        if (self.status === "pending") {
            self.status = "rejected";
            self.reason = reason;
            // 每次調(diào)用 reject 時,執(zhí)行 onRejectedCallbacks 內(nèi)部存儲的所有的函數(shù)(在實現(xiàn) then 方法中詳細說明)
            self.onRejectedCallbacks.forEach(function(fn) {
                fn();
            });
        }
    }

    // 調(diào)用執(zhí)行器函數(shù)
    try {
        executor(resolve, reject);
    } catch (e) {
        // 如果執(zhí)行器執(zhí)行時出現(xiàn)錯誤,直接調(diào)用失敗的函數(shù)
        reject(e);
    }
}

// 將自己的 Promise 導出
module.exports = Promise;

上面構造函數(shù)中的 resolvereject 方法在執(zhí)行的時候都進行了當前狀態(tài)的判斷,只有狀態(tài)為 pending 時,才能執(zhí)行判斷內(nèi)部邏輯,當兩個函數(shù)有一個執(zhí)行后,此時狀態(tài)發(fā)生變化,再執(zhí)行另一個函數(shù)時就不會通過判斷條件,即不會執(zhí)行判斷內(nèi)部的邏輯,從而實現(xiàn)了兩個函數(shù)只有一個執(zhí)行判斷內(nèi)部邏輯的效果,使用如下:

// verify-promise.js -- 驗證 promise.js 的代碼
// 引入自己的 Promise 模塊
// 因為都驗證代碼都寫在 verify-promise.js 文件中,后面就不再引入了
const Promise = require("./promise.js");

let p = new Promise((resolve, reject) => {
    // ...同步代碼
    resolve();
    reject();
    // 上面兩個函數(shù)只有先執(zhí)行的 resolve 生效
});


實例方法的實現(xiàn) 1、then 方法的實現(xiàn)

沒有 Promise 之前在一個異步操作的回調(diào)函數(shù)中返回一個結果在輸入給下一個異步操作,下一個異步操作結束后需要繼續(xù)執(zhí)行回調(diào),就形成回調(diào)函數(shù)的嵌套,在 Promise 中,原來回調(diào)函數(shù)中的邏輯只需要調(diào)用當前 Promise 實例的 then 方法,并在 then 方法的回調(diào)中執(zhí)行,改變了原本異步的書寫方式。

在 then 方法中涉及到的 Promise/A+ 規(guī)范:

Promise 實例的 then 方法中有兩個參數(shù),都為函數(shù),第一個參數(shù)為成功的回調(diào) onFulfilled,第二個參數(shù)為失敗的回調(diào) onRejected;

當 Promise 內(nèi)部執(zhí)行 resolve 時,調(diào)用實例的 then 方法執(zhí)行成功的回調(diào) onFulfilled,當 Promise 內(nèi)部執(zhí)行 reject 或執(zhí)行出錯時,調(diào)用實例的 then 方法執(zhí)行錯誤的回調(diào) onRejected

then 方法需要支持異步,即如果 resovlereject 執(zhí)行為異步時,then 方法的回調(diào) onFulfilledonRejected 需要在后面執(zhí)行;

Promise 需要支持鏈式調(diào)用,Promise 實例調(diào)用 then 方法后需要返回一個新的 Promise 實例。如果 then 的回調(diào)中有返回值且是一個 Promise 實例,則該 Promise 實例執(zhí)行后成功或失敗的結果傳遞給下一個 Promise 實例的 then 方法 onFulfilled (成功的回調(diào))或 onRejected(失敗的回調(diào))的參數(shù),如果返回值不是 Promise 實例,直接將這個值傳遞給下一個 Promise 實例 then 方法回調(diào)的參數(shù),then 的回調(diào)如果沒有返回值相當于返回 undefined;

Promise 實例鏈式調(diào)用 then 時,當任何一個 then 執(zhí)行出錯,鏈式調(diào)用下一個 then 時會執(zhí)行錯誤的回調(diào),錯誤的回調(diào)沒有返回值相當于返回了 undefined,再次鏈式調(diào)用 then 時會執(zhí)行成功的回調(diào);

Promise 實例的鏈式調(diào)用支持參數(shù)穿透,即當上一個 then 沒有傳遞回調(diào)函數(shù),或參數(shù)為 null 時,需要后面調(diào)用的 then 的回調(diào)函數(shù)來接收;

executor 在 Promise 構造函數(shù)中執(zhí)行時使用 try...catch... 捕獲異常,但是內(nèi)部執(zhí)行的代碼有可能是異步的,所以需要在 then 方法中使用 try...catch... 再次捕獲;

Promise 實例的 then 方法中的回調(diào)為 micro-tasks(微任務),回調(diào)內(nèi)的代碼應晚于同步代碼執(zhí)行,在瀏覽器內(nèi)部調(diào)用微任務接口,我們這里模擬使用宏任務代替。

針對上面的 Promise/A+ 規(guī)范,then 方法代碼實現(xiàn)如下:

// promise.js -- then 方法
Promise.prototype.then = function(onFulfilled, onRejected) {
    // 實現(xiàn)參數(shù)穿透
    if(typeof onFulfilled !== "function") {
        onFulfilled = function (data) {
            return data;
        }
    }

    if(typeof onRejected !== "function") {
        onRejected = function (err) {
            throw err;
        }
    }

    // 返回新的 Promise,規(guī)范中規(guī)定這個 Promise 實例叫 promise2
    var promise2 = new Promise(function (resolve, reject) {
        if (this.status === "fulfilled") {
            // 用宏任務替代模擬微任務,目的是使 `then` 的回調(diào)晚于同步代碼執(zhí)行
            setTimeout(function () {
                try {  // 捕獲異步的異常
                    // onFulfilled 執(zhí)行完返回值的處理,x 為成功回調(diào)的返回值
                    var x = onFulfilled(this.value);

                    // 處理返回值多帶帶封裝一個方法
                    resolvePromise(promise2, x, resolve, reject);
                } catch (e) {
                    reject(e);
                }
            }.bind(this), 0);
        }

        if (this.status === "rejected") {
            setTimeout(function () {
                try {
                    // onRejected 執(zhí)行完返回值的處理,x 為失敗回調(diào)的返回值
                    var x = onRejected(this.reason);
                    resolvePromise(promise2, x, resolve, reject);
                } catch (e) {
                    reject(e);
                }
            }.bind(this), 0);
        }

        // 如果在 Promise 執(zhí)行 resolve 或 renject 為異步
        // 將 then 的執(zhí)行程序存儲在實例對應的 onFulfilledCallbacks 或 onRejectedCallbacks 中
        if (this.status === "pending") {
            this.onFulfilledCallbacks.push(function() {
                setTimeout(function () {
                    try {
                        var x = onFulfilled(this.value);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e);
                    }
                }.bind(this), 0);
            });

            this.onRejectedCallbacks.push(function() {
                setTimeout(function () {
                    try {
                        var x = onRejected(this.reason);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e);
                    }
                }.bind(this), 0);
            });
        }
    });

    return promise2;
};

在處理 then 回調(diào)的返回值時,其實就是在處理該返回值與 then 方法在執(zhí)行后返回的新 Promise 實例(即 promise2)之間的關系,因為無論 Promise 的執(zhí)行器在執(zhí)行 resolve 還是 reject 是同步或是異步,都需要進行處理,所以我們多帶帶封裝一個函數(shù) resolvePromise 來處理。

resolvePromise 函數(shù)有四個參數(shù):

promise2:then 執(zhí)行后返回的 Promise 實例;

x:then 的回調(diào)返回的結果;

resolve:promise2 的 resolve 函數(shù);

reject:promise2 的 reject 函數(shù)。

在 resolvePromise 函數(shù)中涉及到的 Promise/A+ 規(guī)范:

將每個 Promise 實例調(diào)用 then 后返回的新 Promise 實例稱為 promise2,將 then 回調(diào)返回的值稱為 x

如果 promise2x 為同一個對象,由于 x 要將執(zhí)行成功或失敗的結果傳遞 promise2then 方法回調(diào)的參數(shù),因為是同一個 Promise 實例,此時既不能成功也不能失?。ㄗ约翰荒艿却约和瓿桑?,造成循環(huán)引用,這種情況下規(guī)定應該拋出一個類型錯誤來回絕;

如果 x 是一個對象或者函數(shù)且不是 null,就去取 xthen 方法,如果 x 是對象,防止 x 是通過 Object.defineProperty 添加 then 屬性,并添加 getset 監(jiān)聽,如果在監(jiān)聽中拋出異常,需要被捕獲到,x.then 是一個函數(shù),就當作 x 是一個 Promise 實例,直接執(zhí)行xthen 方法,執(zhí)行成功就讓 promise2 成功,執(zhí)行失敗就讓 promise2 失敗,如果 x.then 不是函數(shù),則說明 x 為普通值,直接調(diào)用 promise2resolve 方法將 x 傳入,不滿足條件說明該返回值就是一個普通值,直接執(zhí)行 promise2resolve 并將 x 作為參數(shù)傳入;

如果每次執(zhí)行 xthen 方法,回調(diào)中傳入的參數(shù)還是一個 Promise 實例,循環(huán)往復,需要遞歸 resolvePromise 進行解析;

在遞歸的過程中存在內(nèi)、外層同時調(diào)用了 resolvereject 的情況,應該聲明一個標識變量 called 做判斷來避免這種情況。

針對上面的 Promise/A+ 規(guī)范,resolvePromise 函數(shù)代碼實現(xiàn)如下:

// promise.js -- resolvePromise 方法
function resolvePromise(promise2, x, resolve, reject) {
    // 判斷 x 和 promise2 是不是同一個函數(shù)
    if (promise2 === x) {
        reject(new TypeError("循環(huán)引用"));
    }

    // x 是對象或者函數(shù)并且不是 null,如果不滿足該條件說明 x 只是一個普通的值
    if (x !== null && (typeof x === "object" || typeof x === "function")) {
        // 標識變量,防止遞歸內(nèi)外層 resolve 和 reject 同時調(diào)用
        // 針對 Promise,x 為普通值的時候可以放行
        var called;

        // 為了捕獲 Object.defineProperty 創(chuàng)建的 then 屬性時添加監(jiān)聽所拋出的異常
        try {
            var then = x.then;

            if (typeof then === "function") { // then 為一個方法,就當作 x 為一個 promise
                // 執(zhí)行 then,第一個參數(shù)為 this(即 x),第二個參數(shù)為成功的回調(diào),第三個參數(shù)為失敗的回調(diào)
                then.call(x, function (y) {
                    if (called) return;
                    called = true;

                    // 如果 y 是 Promise 就繼續(xù)遞歸解析
                    resolvePromise(promise2, y, resolve, reject);
                }, function (err) {
                    if (called) return;
                    called = true;
                    reject(err);
                });
            } else { // x 是一個普通對象,直接成功即可
                resolve(x);
            }
        } catch(e) {
            if (called) return;
            called = true;
            reject(e);
        }
    } else {
        resolve(x);
    }
}

上面我們按照 Promise/A+ 規(guī)范實現(xiàn)了 Promise 的 then 方法,接下來針對上面的規(guī)范,用一些有針對行的案例來對 then 方法一一進行驗證。

驗證異步調(diào)用 resolvereject

// 文件:verify-promise.js
// 驗證 promise.js 異步調(diào)用 resolve 或 reject
let p = new Promise((resolve, reject) => {
    setTimeout(() => resolve(), 1000);
});

p.then(() => console.log("執(zhí)行了"));

// 執(zhí)行了

驗證鏈式調(diào)用 then 返回 Promise 實例:

// 文件:verify-promise.js
// 驗證 promise.js then 回調(diào)返回 Promise 實例
let p1 = new Promise((resolve, reject) => resolve());
let p2 = new Promise((resolve, reject) => resolve("hello"));

p1.then(() => p2).then(data => console.log(data));

// hello

驗證鏈式調(diào)用 then 返回普通值:

// 文件:verify-promise.js
// 驗證 promise.js then 回調(diào)返回普通值
let p = new Promise((resolve, reject) => resolve());

p.then(() => "hello").then(data => console.log(data));

// hello

驗證鏈式調(diào)用 then 中執(zhí)行出錯鏈式調(diào)用 then 執(zhí)行錯誤的回調(diào)后,再次鏈式調(diào)用 then

// 文件:verify-promise.js
// 驗證 promise.js 鏈式調(diào)用 then 中執(zhí)行出錯鏈式調(diào)用 then 執(zhí)行錯誤的回調(diào)后,再次鏈式調(diào)用 then
let p = new Promise((resolve, reject) => resolve());

p.then(() => {
    throw new Error("error");
}).then(() => {
    console.log("success");
}, err => {
    console.log(err);
}).then(() => {
    console.log("成功");
}, () => {
    console.log("失敗");
});

// Error: error  at p.then...
// 成功

驗證 then 的參數(shù)穿透:

// 文件:verify-promise.js
// 驗證 then 的參數(shù)穿透
let p1 = new Promise((resolve, reject) => resolve("ok"));

let p2 = p1.then().then(data => {
    console.log(data);
    throw new Error("出錯了");
});

p2.then().then(null, err => console.log(err));

// ok
// 出錯了

驗證 then 方法是否晚于同步代碼執(zhí)行:

// 文件:verify-promise.js
// 驗證 then 方法是否晚于同步代碼執(zhí)行
let p = new Promise((resolve, reject) => {
    resolve(1);
});

p.then(data => console.log(data));
console.log(2);

// 2
// 1

驗證循環(huán)引用:

// 文件:verify-promise.js
// 驗證 promise.js 循環(huán)引用
let p1 = new Promise((resolve, reject) => resolve());

// 讓 p1 then 方法的回調(diào)返回自己
var p2 = p1.then(() => {
    return p2;
});

p2.then(() => {
    console.log("成功");
}, err => {
    console.log(err);
});

// TypeError: 循環(huán)引用  at resolvePromise...

驗證 then 回調(diào)返回對象通過 Object.definePropertype 添加 then 屬性并添加 get 監(jiān)聽,在觸發(fā)監(jiān)聽時拋出異常:

// 文件:verify-promise.js
// 驗證 promise.js then 回調(diào)返回對象通過 Object.definePropertype 添加 then 和 get 監(jiān)聽,捕獲異常
let obj = {};
Object.defineProperty(obj, "then", {
    get () {
        throw new Error();
    }
});

let p = new Promise((resolve, reject) => resolve());
p.then(() => {
    return obj;
}).then(() => {
    console.log("成功");
}, () => {
    console.log("出錯了");
});

// 出錯了

驗證每次執(zhí)行 resolve 都傳入 Promise 實例,需要將最終的執(zhí)行結果傳遞給下一個 Promise 實例 then 的回調(diào)中:

// 文件:verify-promise.js
// 驗證 promise.js 每次執(zhí)行 resolve 都傳入 Promise 實例
let p = new Promise((resolve, reject) => resolve());

p.then(() => {
    return new Promise((resolve, reject) => {
        resolve(new Promise(resolve, reject) => {
            resolve(new Promise(resolve, reject) => {
                resolve(200);
            });
        });
    });
}).then(data => {
    console.log(data);
});

// 200
2、catch 方法的實現(xiàn)
// promise.js -- catch 方法
Promise.prototype.catch = function (onRejected) {
    return this.then(null, onRejected);
}

catch 方法可以理解為是 then 方法的一個簡寫,只是參數(shù)中少了成功的回調(diào),所以利用 Promise/A+ 規(guī)范中參數(shù)穿透的特性,很容易就實現(xiàn)了 catch 方法,catch 方法的真相就是這么的簡單。

驗證 catch 方法:

// 文件:verify-promise.js
// 驗證 promise.js 的 catch 方法
let p = new Promise((resolve, reject) => reject("err"));

p.then().catch(err => {
    console.log(err);
}).then(() => {
    console.log("成功了");
});

// err
// 成功了


靜態(tài)方法的實現(xiàn) 1、Promise.resolve 方法的實現(xiàn)

Promise.resolve 方法傳入一個參數(shù),并返回一個新的 Promise 實例,這個參數(shù)作為新 Promise 實例 then 方法成功回調(diào)的參數(shù),在調(diào)用時感覺直接成功了,其實是直接執(zhí)行了返回 Promise 實例的 resolve。

// promise.js -- Promise.resolve 方法
Promise.resolve = function (val) {
    return new Promise(function (resolve, reject) {
        resolve(val);
    });
}

驗證 Promise.resolve 方法:

// 文件:verify-promise.js
// 驗證 promise.js 的 Promise.resolve 方法
Promise.resolve("成功了").then(data => console.log(data));

// 成功了
2、Promise.reject 方法的實現(xiàn)

Promise.reject 方法與 Promise.resolve 的實現(xiàn)思路相同,不同的是,直接調(diào)用了返回新 Promise 實例的 reject。

// promise.js -- Promise.reject 方法
Promise.reject = function (reason) {
    return new Promise(function (resolve, reject) {
        reject(reason);
    });
}

驗證 Promise.reject 方法:

// 文件:verify-promise.js
// 驗證 promise.js 的 Promise.reject 方法
Promise.reject("失敗了").then(err => console.log(err));

// 失敗了
3、Promise.all 方法的實現(xiàn)

Promise.all 方法可以實現(xiàn)多個 Promise 實例的并行,返回值為一個新的 Promise 實例,當所有結果都為成功時,返回一個數(shù)組,該數(shù)組存儲的為每一個 Promise 實例的返回結果,這些 Promise 實例的返回順序先后不確定,但是返回值的數(shù)組內(nèi)存儲的返回結果是按照數(shù)組中 Promise 實例最初順序進行排列的,返回的數(shù)組作為返回 Promise 實例成功回調(diào)的參數(shù),當其中一個失敗,直接返回錯誤信息,并作為返回 Promise 實例失敗回調(diào)的參數(shù)。

// promise.js -- Promise.all 方法
Promise.all = function (promises) {
    return new Promise(function (resolve, reject) {
        // 存儲返回值
        var result = [];
        // 代表存入的個數(shù),因為 Promise 為異步,不知道哪個 Promise 先成功,不能用數(shù)組的長度來判斷
        var idx = 0;

        // 用來構建全部成功的返回值
        function processData(index, data) {
            result[index] = data; // 將返回值存入數(shù)組
            idx++;

            if (idx === promises.length) {
                resolve(result);
            }
        }

        for(var i = 0; i < promises.length; i++) {
            // 因為 Primise 為異步,保證 i 值是順序傳入
            (function (i) {
                promises[i].then(function (data) {
                    processData(i, data);
                }, reject);
            })(i);
        }
    });
}

驗證 Promise.all 方法:

// 文件:verify-promise.js
// 驗證 promise.js 的 Promise.all 方法
let p1 = new Promise((resolve, reject) => setTimeout(() => resolve(1), 2000));
let p2 = new Promise((resolve, reject) => setTimeout(() => resolve(2), 1000));

Promise.all([p1, p2]).then(data => console.log(data));

// [1, 2]

let p3 = new Promise((resolve, reject) => setTimeout(() => resolve(1), 2000));
let p4 = new Promise((resolve, reject) => setTimeout(() => reject(2), 1000));

Promise.all([p3, p4]).then(data => {
    console.log(data);
}).catch(err => {
    console.log(err);
});

// 2
4、Promise.race 方法的實現(xiàn)

Promise.race 方法與 Promise.all 類似,同樣可以實現(xiàn)多個 Promise 實例的并行,同樣返回值為一個新的 Promise 實例,參數(shù)同樣為一個存儲多個 Promise 實例的數(shù)組,區(qū)別是只要有一個 Promise 實例返回結果,無論成功或失敗,則直接返回這個結果,并作為新 Promise 實例 then 方法中成功或失敗的回調(diào)函數(shù)的參數(shù)。

// promise.js -- Promise.race 方法
Promise.race = function (promises) {
    return new Promise(function (resolve, reject) {
        for(var i = 0; i < promises.length; i++) {
            promises[i].then(resolve, reject);
        }
    });
}

驗證 Promise.race 方法:

// 文件:verify-promise.js
// 驗證 promise.js 的 Promise.race 方法
let p1 = new Promise((resolve, reject) => setTimeout(() => resolve(1), 2000));
let p2 = new Promise((resolve, reject) => setTimeout(() => resolve(2), 1000));

Promise.race([p1, p2]).then(data => console.log(data));

// 2

let p3 = new Promise((resolve, reject) => setTimeout(() => resolve(1), 2000));
let p4 = new Promise((resolve, reject) => setTimeout(() => reject(2), 1000));

Promise.all([p3, p4]).then(data => {
    console.log(data);
}).catch(err => {
    console.log(err);
});

// 2


使用 promises-aplus-test 測試 Promise 是否符合 Promise/A+ 規(guī)范

promises-aplus-test 是專門用來驗證 Promise 代碼是否符合 Promise/A+ 規(guī)范的包,需要通過 npm 下載。

npm install promises-aplus-test -g

測試方法:

promise.js 中寫入測試代碼;

在命令行中輸入命令 promises-aplus-test + fileName

測試代碼:

// promise.js -- 測試方法 Promise.derfer
// Promise 語法糖
// 好處:解決 Promise 嵌套問題
// 壞處:錯誤處理不方便
Promise.derfer = Promise.deferred = function () {
    let dfd = {};

    dfd.promise = new Promise((resolve, reject) => {
        dfd.resolve = resolve;
        dfd.reject = reject;
    });

    return dfd;
}

輸入命令:

promises-aplus-test promise.js

執(zhí)行上面命令后,會根據(jù) Promise/A+ 規(guī)范一條一條進行極端的驗證,當驗證通過后會在窗口中這一條對應的執(zhí)行項前打勾,驗證不通過打叉,直到所有的規(guī)范都驗證完畢。


文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/98281.html

相關文章

  • 異步發(fā)展流程 —— 異步編程終極大招 async/await

    摘要:簡介指的是兩個關鍵字,是引入的新標準,關鍵字用于聲明函數(shù),關鍵字用來等待異步必須是操作,說白了就是的語法糖。最后希望大家在讀過異步發(fā)展流程這個系列之后,對異步已經(jīng)有了較深的認識,并可以在不同情況下游刃有余的使用這些處理異步的編程手段。 showImg(https://segmentfault.com/img/remote/1460000018998406?w=1024&h=379); ...

    zhangfaliang 評論0 收藏0
  • JavaScript 異步

    摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。寫一個符合規(guī)范并可配合使用的寫一個符合規(guī)范并可配合使用的理解的工作原理采用回調(diào)函數(shù)來處理異步編程。 JavaScript怎么使用循環(huán)代替(異步)遞歸 問題描述 在開發(fā)過程中,遇到一個需求:在系統(tǒng)初始化時通過http獲取一個第三方服務器端的列表,第三方服務器提供了一個接口,可通過...

    tuniutech 評論0 收藏0
  • 手寫一款符合Promise/A+規(guī)范Promise

    摘要:手寫一款符合規(guī)范的長篇預警有點長,可以選擇性觀看。初始狀態(tài)是,狀態(tài)可以有或者不能從轉換為或者從轉換成即只要由狀態(tài)轉換為其他狀態(tài)后,狀態(tài)就不可變更。 手寫一款符合Promise/A+規(guī)范的Promise 長篇預警!有點長,可以選擇性觀看。如果對Promise源碼不是很清楚,還是推薦從頭看,相信你認真從頭看到尾,并且去實際操作了,肯定會有收獲的。主要是代碼部分有點多,不過好多都是重復的,不...

    rubyshen 評論0 收藏0
  • 異步發(fā)展流程 —— Generators + co 讓異步更優(yōu)雅

    摘要:遍歷器原有的表示集合的數(shù)據(jù)結構,主要有和,在中又加入了和,這樣就有了四種數(shù)據(jù)集合,還可以組合使用它們,如數(shù)組的成員是或,這樣就需要一種統(tǒng)一的接口機制,用來處理所有不同的數(shù)據(jù)結構。 showImg(https://segmentfault.com/img/remote/1460000018998438?w=900&h=431); 閱讀原文 Generators 簡介 Generato...

    dingda 評論0 收藏0
  • 手寫一個符合promise/A+規(guī)范promise

    摘要:使用及原理分析通過關鍵字創(chuàng)建實例接受一個參數(shù)方法返回兩個方法可用通過在方法中通過調(diào)用使成功或調(diào)用使失敗來控制狀態(tài)中可以執(zhí)行同步代碼也可以執(zhí)行異步代碼原型對象上有方法供實例調(diào)用方法接受兩個參數(shù)默認為一個函數(shù)默認為一個函數(shù)當狀態(tài)為時執(zhí)行用戶傳入 promise使用及原理分析: 通過new關鍵字創(chuàng)建promise實例, 接受一個executor參數(shù), executor方法返回兩個方法 res...

    venmos 評論0 收藏0

發(fā)表評論

0條評論

UnixAgain

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<