摘要:主要邏輯本質(zhì)上還是回調(diào)函數(shù)那一套。通過(guò)的判斷完成異步和同步的區(qū)分。
主要邏輯:
本質(zhì)上還是回調(diào)函數(shù)那一套。
通過(guò)_subscribers的判斷完成異步和同步的區(qū)分。
通過(guò) resolve,reject -> publish -> invokeCallback -> resolve,reject的遞歸和下一條then的parent是上一條的child來(lái)完成then鏈的流轉(zhuǎn)
同步情況下函數(shù)流轉(zhuǎn): constructor -> resolver -> publish -> then -> invokeCallback
異步情況下函數(shù)流轉(zhuǎn): constructor -> then -> resolver -> publish -> invokeCallback
主要函數(shù)解析
1. constructor
作用: 把resolve,reject綁定到 resolver上-
constructor(resolver) { this[PROMISE_ID] = nextId(); this._result = this._state = undefined; this._subscribers = []; if (noop !== resolver) { typeof resolver !== "function" && needsResolver(); this instanceof Promise ? initializePromise(this, resolver) : needsNew(); } }
2 then
作用: 把回調(diào)函數(shù)綁定在_subscribers上,catch和finally本質(zhì)是then的語(yǔ)法糖
_subscribers的參數(shù)是一個(gè)數(shù)組,[0]是他的child,綁定下一個(gè)then鏈的parent,用于publish遞歸調(diào)用, 第二個(gè)是resolve 回調(diào), 第三個(gè)是reject回調(diào)
export default function then(onFulfillment, onRejection) { const parent = this; const child = new this.constructor(noop); if (child[PROMISE_ID] === undefined) { makePromise(child); } const { _state } = parent; if (_state) { const callback = arguments[_state - 1]; asap(() => invokeCallback(_state, child, callback, parent._result)); } else { subscribe(parent, child, onFulfillment, onRejection); } return child; }
3 publish
作用: resolve,reject的觸發(fā)會(huì)調(diào)用publish,publish繼續(xù)調(diào)用invokeCallback,通過(guò)返回值繼續(xù)調(diào)用resolve,reject,形成一個(gè)遞歸,完成then鏈的流轉(zhuǎn)
function publish(promise) { let subscribers = promise._subscribers; let settled = promise._state; if (subscribers.length === 0) { return; } let child, callback, detail = promise._result; for (let i = 0; i < subscribers.length; i += 3) { child = subscribers[i]; callback = subscribers[i + settled]; if (child) { invokeCallback(settled, child, callback, detail); } else { callback(detail); } } promise._subscribers.length = 0; }
tip:
finally的callback是沒(méi)有返回參數(shù)的,基于
return promise.then(value => constructor.resolve(callback()).then(() => value), reason => constructor.resolve(callback()).then(() => { throw reason; }));
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/102845.html
摘要:是什么可以理解為一個(gè)承諾,如果調(diào)用,返回一個(gè)承諾給,然后就可以在寫計(jì)劃的時(shí)候這么寫,當(dāng)返回結(jié)果的時(shí)候,就執(zhí)行方案,如果沒(méi)有返回要的結(jié)果,就執(zhí)行方案。這樣一來(lái),所有的潛在風(fēng)險(xiǎn)就都在的可控范圍之內(nèi)了。 promise是什么 Promise可以理解為一個(gè)承諾,如果A調(diào)用B,B返回一個(gè)承諾給A,然后A就可以在寫計(jì)劃的時(shí)候這么寫,當(dāng)B返回結(jié)果的時(shí)候,A就執(zhí)行方案1,如果B沒(méi)有返回A要的結(jié)果,A就...
摘要:做前端路由管理,一個(gè)中大型項(xiàng)目必須要做路由管理做數(shù)據(jù)管理,類似于的存在,沒(méi)有,中大型應(yīng)用中的狀態(tài)會(huì)把開(kāi)發(fā)者搞死,絕對(duì)。 想做SPA就快上車! init 首先要起一個(gè)項(xiàng)目,推薦用vue-cli安裝 $ npm install -g vue-cli $ vue init webpack demo $ cd demo $ npm install demo是這個(gè)示例項(xiàng)目的名字 現(xiàn)在看到目錄結(jié)構(gòu)...
為什么讀webpack源碼 因?yàn)榍岸丝蚣茈x不開(kāi)webpack,天天都在用的東西啊,怎能不研究 讀源碼能學(xué)到很多做項(xiàng)目看書學(xué)不到的東西,比如說(shuō)架構(gòu),構(gòu)造函數(shù),es6很邊緣的用法,甚至給函數(shù)命名也會(huì)潛移默化的影響等 想寫源碼,不看源碼怎么行,雖然現(xiàn)在還不知道寫什么,就算不寫什么,看看別人寫的總可以吧 知道世界的廣闊,那么多插件,那么多軟件開(kāi)發(fā)師,他們?cè)谧鍪裁?,同樣是寫js的,怎么他們能這么偉大 好奇...
摘要:前言本文的目的是閱讀理解的源碼,作為集合中重要的一個(gè)角色,平時(shí)用到十分多的一個(gè)類,深入理解它,知其所以然很重要。 前言 本文的目的是閱讀理解HashMap的源碼,作為集合中重要的一個(gè)角色,平時(shí)用到十分多的一個(gè)類,深入理解它,知其所以然很重要。本文基于Jdk1.7,因?yàn)镴dk1.8改變了HashMap的數(shù)據(jù)結(jié)構(gòu),進(jìn)行了優(yōu)化,我們先從基礎(chǔ)閱讀,之后再閱讀理解Jdk1.8的內(nèi)容 HashMa...
摘要:大多的初學(xué)者都會(huì)使用中間件來(lái)處理異步請(qǐng)求,其理解簡(jiǎn)單使用方便具體使用可參考官方文檔。源碼的源碼非常簡(jiǎn)潔,出去空格一共只有行,這行中如果不算上則只有行。官方文檔中的一節(jié)講解的非常好,也確實(shí)幫我理解了中間件的工作原理,非常推薦閱讀。 總覺(jué)得文章也應(yīng)該是有生命力的,歡迎關(guān)注我的Github上的博客,這里的文章會(huì)依據(jù)我本人的見(jiàn)識(shí),逐步更新。 大多redux的初學(xué)者都會(huì)使用redux-thunk...
閱讀 3864·2021-08-30 09:47
閱讀 3855·2019-08-30 15:56
閱讀 734·2019-08-30 14:18
閱讀 760·2019-08-29 16:17
閱讀 2115·2019-08-29 11:07
閱讀 690·2019-08-26 13:53
閱讀 3504·2019-08-26 10:26
閱讀 2546·2019-08-23 18:30