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