摘要:鏈式調用解析關于是做什么的我就不贅述了,當你看到這個文章的時候,我也就默認你是用過的首先,舉個例子獲取用戶通過用戶獲取該用戶的手機號兩個方法,簡稱和簡稱兩者都是了一個實例,前者是獲取用戶,后者是拿著用戶去換取手機號,的輸出是依賴于的輸出,這
Promise鏈式調用解析
關于Promise是做什么的我就不贅述了,當你看到這個文章的時候,我也就默認你是用過Promise的
首先,舉個例子
// 獲取用戶id function getUserId() { return new Promise(function(resolve, reject) { setTimeout(function() { resolve(186) }, 1e3) }) } // 通過用戶id獲取該用戶的手機號 function getMobileByUserId(userId) { return new Promise(function(resolve, reject) { setTimeout(function(){ resolve(userId + "****5836") }, 1e3) }) }
兩個方法,getUserId(簡稱 IDfun )和getMobileByUserId(簡稱 MOfun ),兩者都是return了一個Promise實例,前者是獲取用戶id,后者是拿著用戶id去換取手機號,MOfun的輸出是依賴于IDfun的輸出,這樣兩個異步的操作又得保證其是有序的執行
到這,應該都有一個對應的解決辦法,我這里列舉了一個示例:
IDfun() .then(MOfun) .then(function(res) { console.log(res) })
首先,調用了IDfun,在其Promise實例的then方法中傳入MOfun,緊隨其后又是一個then方法,里面傳入了一個callback函數,此時,callback函數中打印的值是什么,又是為什么呢,一般情況下then方法里傳的都是一個callback,而這個例子里傳的卻是一個包含Promise的函數,它內部是怎么做到將用戶的id傳遞給MOfun中并打印出來
說到這,我先列舉幾個Promise中幾個比較核心的方法:
// this指向是Promise實例 // 只列舉了幾個關鍵的代碼 this.then = function (onFulfilled) { return new Promise(function (resolve) { handle({ onFulfilled: onFulfilled || null, resolve: resolve }); }); }; function handle(deferred) { if (state === "pending") { deferreds.push(deferred); return; } var ret = deferred.onFulfilled(value); deferred.resolve(ret); } // 其中的state和value可以理解為全局定義的,只是放了一些代碼段出來 function resolve(newValue) { if (newValue && (typeof newValue === "object" || typeof newValue === "function")) { var then = newValue.then; if (typeof then === "function") { then.call(newValue, resolve); return; } } state = "fulfilled"; value = newValue; // value這里可以理解為它是在全局定義的 setTimeout(function () { deferreds.forEach(function (deferred) { handle(deferred); }); }, 0); }
參照這幾個方法,我們再回到剛才那個例子:
1.執行IDfun返回一個Promise實例( IDPro ),執行IDPro中的代碼,假設此時在異步發送請求,繼續執行then方法,then方法中傳入了MOfun
2.進入到then方法中,也是返回一個Promise實例( BridgePro1 ),調用handle方法
handle({
onFulfilled: onFulfilled || null, // 此時的onFulfilled === MOfun resolve: resolve // resolve是BridgePro1的resolve
});
3.進入handle中,如果是IDPro的then方法先執行,其resolve后執行,這個時候 state === pending,此時它會將傳入的對象push到IDPro的deferreds數組中,然后返回
4.IDPro中異步操作完成,執行其resolve,并傳入id為186
5.進入resolve方法中,此時newValue不滿足if條件,跳過,繼續向下執行,改變state===> fulfilled,value ===> 186,setTimeout為0是為了把其內部的這段代碼放到隊列的最后,保證執行這段代碼的時候then方法已經執行了,循環遍歷IDPro的deferreds數組,將數組中的每一項傳入handle中并執行
function resolve(newValue) { // newValue === 186 if (newValue && (typeof newValue === "object" || typeof newValue === "function")) { var then = newValue.then; if (typeof then === "function") { then.call(newValue, resolve); return; } } state = "fulfilled"; value = newValue; // value這里可以理解為它是在全局定義的 setTimeout(function () { // deferreds里存放的是通過then傳入的 // [{ // onFulfilled: MOfun, // resolve: resolve // }] deferreds.forEach(function (deferred) { handle(deferred); }); }, 0); }
6.進入handle中,此時state === fulfilled,執行deferred中的onFulfilled(MOfun),傳入value,返回一個Promise實例(MOPro),此時的ret === MOPro,繼續執行deferred中的resolve(BridgePro1的resolve),傳入ret
// state === fulfilled // deferred ===> // { // onFulfilled: MOfun, // resolve: resolve // } function handle(deferred) { if (state === "pending") { deferreds.push(deferred); return; } var ret = deferred.onFulfilled(value); // value === 186 deferred.resolve(ret); }
7.進入resolve中,此時newValue滿足判斷條件
function resolve(newValue) { // newValue === MOPro if (newValue && (typeof newValue === "object" || typeof newValue === "function")) { // then 是MOPro的then var then = newValue.then; if (typeof then === "function") { // 調用then方法,設置其內部this指向為MOPro,并傳入resolve,這個resolve為BridgePro1的resolve,然后返回 then.call(newValue, resolve); return; } } state = "fulfilled"; value = newValue; setTimeout(function () { deferreds.forEach(function (deferred) { handle(deferred); }); }, 0); }
8.進入到MOPro的then方法中,調用handle將對象傳入,此時MOPro的deferreds數組中有兩項,一項是上面通過resolve傳入的,另一項是傳入的callback函數
// ===> callback function(res) { console.log(res) } this.then = function (onFulfilled) { // onFulfilled為BridgePro1的resolve // 此時返回的Promise實例為BridgePro2 return new Promise(function (resolve) { handle({ onFulfilled: onFulfilled || null, resolve: resolve // BridgePro2 }); }); };
9.當MOPro中異步操作執行完成,執行resolve并傳入手機號1865836,進入resolve,將state設置為fulfilled,value設置成1865836,延遲循環MOPro的deferreds數組,此時數組為:
[ { onFulfilled: resolve, // BridgePro1的resolve resolve: resolve // BridgePro2的resolve }, { onFulfilled: callback, resolve: resolve // BridgePro3的resolve } ]
10.進入handle方法中,循環第一個值時,此時deferred的onFulfilled為BridgePro1的resolve,調用該resolve,并傳入value(1865836),因為BridgePro1的deferreds為空,所以直接resolve掉BridgePro1,此時ret為undefined,再執行deferred的resolve(BridgePro2的resolve),同樣,resolve掉BridgePro2,繼續循環,傳入第二個值,deferred的onFulfilled為callback,執行callback傳入value,打印出手機號1865836,返回值為undefined ,因此ret為undefined,再執行deferred的resolve(BridgePro3的resolve),直接resolve掉BridgePro3
function handle(deferred) { if (state === "pending") { deferreds.push(deferred); return; } var ret = deferred.onFulfilled(value); deferred.resolve(ret); }
11.至此,執行完成,通過user的id換取了user的mobile number
后記:如果我想按照下面的寫法一直then下去:
IDfun() .then(MOfun) .then(callback) .then(callback) .then(callback)
每個callback里都可以打印到手機號,應該怎么寫
// callback function callback(res) { // doing something console.log(res) return res }總結:
Promise是什么,從字面意思就是一個承諾,我給你了一個承諾,你記著呢,不知道什么時候兌現,但肯定會給你一個答復,打一個不太形象的比喻,我去銀行辦事,肯定是先取一個號,這個號就像一個承諾,什么時候叫到你,不確定,但肯定會叫你,然后這個時候你就會去辦理你的事情,綜上,即為Promise鏈式的原理解析,出錯的地方歡迎指出
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/99236.html
摘要:原文地址定義是針對異步編程的一種解決方案,能夠抽象處理異步對象以及對其進行操作。當狀態由時執行已完成的回調函數,由時,調用失敗的回調函數。所以,可以在自行使用,保證執行不會出錯,或者使用其他異步編程方式。異步編程的方案后續學習再補充 原文地址 定義 Promise是針對異步編程的一種解決方案,能夠抽象處理異步對象以及對其進行操作。Promise并不是Javascript語言的擴展,只是...
摘要:規范中文是提供的一個服務。實際調用這個方法最終在此處加入到隊列中定義此處調用進入此處是鏈式調用傳參關鍵,實際是上一個的的返回值,所以能知道,如果需要所有的都能取到異步任務的返回值,就得在的函數中,將值返回。 promise是什么 這里不解釋promise是什么,因為我相信你來看文章的時候已經知道你什么是promise了。此處有promise規范。 Promise/A+規范 中文Prom...
摘要:函數會在之后的某個時刻觸發事件定時器。事件循環中的這樣一次遍歷被稱為一個。執行完畢并出棧。當定時器過期,宿主環境會把回調函數添加至事件循環隊列中,然后,在未來的某個取出并執行該事件。 原文請查閱這里,略有改動。 本系列持續更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第四章。 現在,我們將會通過回顧單線程環境下編程的弊端及如何克服這些困難以創建令人驚嘆...
閱讀 1724·2021-11-11 10:58
閱讀 4210·2021-09-09 09:33
閱讀 1267·2021-08-18 10:23
閱讀 1555·2019-08-30 15:52
閱讀 1632·2019-08-30 11:06
閱讀 1877·2019-08-29 14:03
閱讀 1513·2019-08-26 14:06
閱讀 2960·2019-08-26 10:39