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