摘要:構造函數(shù)的實現(xiàn)我們在使用的時候其實是使用關鍵字創(chuàng)建了一個的實例,其實是一個類,即構造函數(shù),下面來實現(xiàn)構造函數(shù)。
Promise 是 js 異步編程的一種解決方案,避免了 “回調(diào)地獄” 給編程帶來的麻煩,在 ES6 中成為了標準,這篇文章重點不是敘述 Promise 的基本用法,而是從零開始,手寫一版符合 Promise/A+ 規(guī)范的 Promise,如果想了解更多 Promise 的基本用法,可以看 異步發(fā)展流程 —— Promise 的基本使用 這篇文章。
我們在使用 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ù)分別為 resolve 和 reject,一個為成功時執(zhí)行的函數(shù),一個為失敗時執(zhí)行的函數(shù);
在 executor 執(zhí)行時,一旦出現(xiàn)錯誤立即調(diào)用 reject 函數(shù),并設置錯誤信息給 reason 屬性;
每個 Promise 實例有三個狀態(tài) pending、fulfilled 和 rejected,默認狀態(tài)為 pending;
狀態(tài)只能從 pending 到 fulfilled 或從 pending 到 rejected,且不可逆;
執(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ù)中的 resolve 和 reject 方法在執(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 生效 });
沒有 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 方法需要支持異步,即如果 resovle 或 reject 執(zhí)行為異步時,then 方法的回調(diào) onFulfilled 或 onRejected 需要在后面執(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;
如果 promise2 和 x 為同一個對象,由于 x 要將執(zhí)行成功或失敗的結果傳遞 promise2 的 then 方法回調(diào)的參數(shù),因為是同一個 Promise 實例,此時既不能成功也不能失?。ㄗ约翰荒艿却约和瓿桑?,造成循環(huán)引用,這種情況下規(guī)定應該拋出一個類型錯誤來回絕;
如果 x 是一個對象或者函數(shù)且不是 null,就去取 x 的 then 方法,如果 x 是對象,防止 x 是通過 Object.defineProperty 添加 then 屬性,并添加 get 和 set 監(jiān)聽,如果在監(jiān)聽中拋出異常,需要被捕獲到,x.then 是一個函數(shù),就當作 x 是一個 Promise 實例,直接執(zhí)行x 的 then 方法,執(zhí)行成功就讓 promise2 成功,執(zhí)行失敗就讓 promise2 失敗,如果 x.then 不是函數(shù),則說明 x 為普通值,直接調(diào)用 promise2 的 resolve 方法將 x 傳入,不滿足條件說明該返回值就是一個普通值,直接執(zhí)行 promise2 的 resolve 并將 x 作為參數(shù)傳入;
如果每次執(zhí)行 x 的 then 方法,回調(diào)中傳入的參數(shù)還是一個 Promise 實例,循環(huán)往復,需要遞歸 resolvePromise 進行解析;
在遞歸的過程中存在內(nèi)、外層同時調(diào)用了 resolve 和 reject 的情況,應該聲明一個標識變量 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)用 resolve 或 reject:
// 文件: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); }); // 2002、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 // 成功了
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); }); // 24、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ī)范的包,需要通過 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
摘要:簡介指的是兩個關鍵字,是引入的新標準,關鍵字用于聲明函數(shù),關鍵字用來等待異步必須是操作,說白了就是的語法糖。最后希望大家在讀過異步發(fā)展流程這個系列之后,對異步已經(jīng)有了較深的認識,并可以在不同情況下游刃有余的使用這些處理異步的編程手段。 showImg(https://segmentfault.com/img/remote/1460000018998406?w=1024&h=379); ...
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。寫一個符合規(guī)范并可配合使用的寫一個符合規(guī)范并可配合使用的理解的工作原理采用回調(diào)函數(shù)來處理異步編程。 JavaScript怎么使用循環(huán)代替(異步)遞歸 問題描述 在開發(fā)過程中,遇到一個需求:在系統(tǒng)初始化時通過http獲取一個第三方服務器端的列表,第三方服務器提供了一個接口,可通過...
摘要:手寫一款符合規(guī)范的長篇預警有點長,可以選擇性觀看。初始狀態(tài)是,狀態(tài)可以有或者不能從轉換為或者從轉換成即只要由狀態(tài)轉換為其他狀態(tài)后,狀態(tài)就不可變更。 手寫一款符合Promise/A+規(guī)范的Promise 長篇預警!有點長,可以選擇性觀看。如果對Promise源碼不是很清楚,還是推薦從頭看,相信你認真從頭看到尾,并且去實際操作了,肯定會有收獲的。主要是代碼部分有點多,不過好多都是重復的,不...
摘要:遍歷器原有的表示集合的數(shù)據(jù)結構,主要有和,在中又加入了和,這樣就有了四種數(shù)據(jù)集合,還可以組合使用它們,如數(shù)組的成員是或,這樣就需要一種統(tǒng)一的接口機制,用來處理所有不同的數(shù)據(jù)結構。 showImg(https://segmentfault.com/img/remote/1460000018998438?w=900&h=431); 閱讀原文 Generators 簡介 Generato...
摘要:使用及原理分析通過關鍵字創(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...
閱讀 435·2019-08-29 12:44
閱讀 3013·2019-08-26 17:49
閱讀 2443·2019-08-26 13:40
閱讀 1189·2019-08-26 13:39
閱讀 3668·2019-08-26 11:59
閱讀 1830·2019-08-26 10:59
閱讀 2469·2019-08-23 18:33
閱讀 2698·2019-08-23 18:30