原文鏈接:鏈接
1 最簡(jiǎn)單一個(gè)案例function runAsync(){ let p = new Promise(function(resolve,reject){ console.log("exec"); setTimeout(function(){ resolve("someData"); },2000); }); return p; } var promise = runAsync(); promise.then(function(data){ console.log(data); }); console.log("同步執(zhí)行"); console.log(promise);
控制臺(tái)輸出
exec 同步執(zhí)行 Promise //兩秒后 someData2 Promise內(nèi)部是如何運(yùn)行的? 2.1 執(zhí)行這行代碼的時(shí)候:let p = new Promise(f);
function noop() {} function Promise(fn) { if (typeof this !== "object") { throw new TypeError("Promises must be constructed via new"); } if (typeof fn !== "function") { throw new TypeError("Promise constructor"s argument is not a function"); } this._deferredState = 0; this._state = 0; this._value = null; this._deferreds = null; //注意這里,如果fn傳入的是noop這個(gè)函數(shù),那么不會(huì)執(zhí)行doResolve if (fn === noop) return; doResolve(fn, this); } Promise._onHandle = null; Promise._onReject = null; Promise._noop = noop; function doResolve(fn, promise) { var done = false; var res = tryCallTwo(fn, function (value) { if (done) return; done = true; resolve(promise, value); }, function (reason) { if (done) return; done = true; reject(promise, reason); }); if (!done && res === IS_ERROR) { done = true; reject(promise, LAST_ERROR); } } function tryCallTwo(fn, a, b) { try { fn(a, b); } catch (ex) { LAST_ERROR = ex; return IS_ERROR; } }
可以看到 let p = new Promise( f );在 傳入的 f. 函數(shù)不是noop的時(shí)候,
第一會(huì)先執(zhí)行 f 函數(shù)
第二生成一個(gè)Promise對(duì)象
p =>{ _deferredState:0,//deffer的狀態(tài),代表的應(yīng)該是 _deferreds 的類型,1 是 single,2 是 Array _state:0,//每個(gè)promise對(duì)象的狀態(tài)維護(hù)標(biāo)識(shí) _value:null,//resolve函數(shù)執(zhí)行的時(shí)候,異步得到的結(jié)果 _deferreds:null }2.2執(zhí)行這行代碼的時(shí)候: promise.then(function(data){ console.log(data);});
Promise.prototype.then = function(onFulfilled, onRejected) { if (this.constructor !== Promise) {//這些比較的都是引用地址; return safeThen(this, onFulfilled, onRejected); } var res = new Promise(noop); handle(this, new Handler(onFulfilled, onRejected, res)); //注意這里 then的鏈?zhǔn)秸{(diào)用,每次then函數(shù)執(zhí)行完畢之后,返回值都是一個(gè)新的Promise實(shí)例對(duì)象, return res; }; //這里生成一個(gè)deffer對(duì)象,保存then函數(shù)中注冊(cè)的onFulfilled和onRejected回調(diào),以及要返回的新的promise實(shí)例對(duì)象 function Handler(onFulfilled, onRejected, promise){ this.onFulfilled = typeof onFulfilled === "function" ? onFulfilled : null; this.onRejected = typeof onRejected === "function" ? onRejected : null; this.promise = promise; } function handle(self, deferred) { //不會(huì)進(jìn)入這里 while (self._state === 3) { self = self._value; } //也不會(huì)進(jìn)入這里 if (Promise._onHandle) { Promise._onHandle(self); } //進(jìn)入這里,注意這里,如果通過then的鏈?zhǔn)秸{(diào)用,那么每次then返回的對(duì)象都是一個(gè)新的類似于下面 p 實(shí)例對(duì)象; if (self._state === 0) { if (self._deferredState === 0) { self._deferredState = 1; self._deferreds = deferred; return; //第一次執(zhí)行到這里即結(jié)束; } if (self._deferredState === 1) { self._deferredState = 2; self._deferreds = [self._deferreds, deferred]; return; } self._deferreds.push(deferred); return; } //這個(gè)函數(shù)只有當(dāng) _state的值為 1 2的時(shí)候才會(huì)執(zhí)行 handleResolved(self, deferred); }
此時(shí)再來看下p這個(gè)promise實(shí)例的屬性值
p =>{ _deferredState:1,//deffer的狀態(tài) _state:0,//每個(gè)promise對(duì)象的狀態(tài)維護(hù)標(biāo)識(shí) _value:null,//resolve函數(shù)執(zhí)行的時(shí)候,異步得到的結(jié)果 _deferreds: new Handler(onFulfilled, onRejected, res)//存放通過then注冊(cè)的函數(shù)以及返回的??Promise實(shí)例對(duì)象的一個(gè)Handler對(duì)象; } res:{ _deferredState:0,//deffereds的狀態(tài), _state:0,//每個(gè)promise對(duì)象的狀態(tài)維護(hù)標(biāo)識(shí) _value:null,//resolve函數(shù)執(zhí)行的時(shí)候,異步得到的結(jié)果 _deferreds:null }
如果返回的res在執(zhí)行then方法,那么
p =>{ _deferredState:1,//deffer的狀態(tài) _state:0,//每個(gè)promise對(duì)象的狀態(tài)維護(hù)標(biāo)識(shí) _value:null,//resolve函數(shù)執(zhí)行的時(shí)候,異步得到的結(jié)果 _deferreds: new Handler(onFulfilled, onRejected, res)//存放通過then注冊(cè)的函數(shù)以及返回的??Promise實(shí)例對(duì)象的一個(gè)Handler對(duì)象; } res:{ _deferredState:1,//deffereds的狀態(tài), _state:0,//每個(gè)promise對(duì)象的狀態(tài)維護(hù)標(biāo)識(shí) _value:null,//resolve函數(shù)執(zhí)行的時(shí)候,異步得到的結(jié)果 _deferreds:new Handler(onFulfilled, onRejected, res)//存放通過then注冊(cè)的函數(shù)以及返回的??Promise實(shí)例對(duì)象的一個(gè)Handler對(duì)象; }2.3 異步操作完成以后:resolve("someData");
//真正調(diào)用這個(gè)函數(shù)的是tryCallTwo中的第二個(gè)函數(shù)入?yún)ⅲ籹elf就是p這個(gè)promise實(shí)例對(duì)象; function resolve(self, newValue) { // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure //對(duì)于此時(shí)的案例,不會(huì)進(jìn)入這里 if (newValue === self) { return reject( self, new TypeError("A promise cannot be resolved with itself.") ); } //也不會(huì)進(jìn)入這里 if ( //比如resolve(p1) p1是一個(gè)新的promise對(duì)象; newValue && (typeof newValue === "object" || typeof newValue === "function") ) { var then = getThen(newValue); if (then === IS_ERROR) { return reject(self, LAST_ERROR); } if ( then === self.then && newValue instanceof Promise ) { self._state = 3; self._value = newValue; finale(self); return; } else if (typeof then === "function") { doResolve(then.bind(newValue), self); return; } } //對(duì)于簡(jiǎn)單的返回值,比如后臺(tái)返回的JSON字符串等,這里就直接進(jìn)行處理; self._state = 1;//fulfilled self._value = newValue;//給這個(gè)promise對(duì)象添加屬性值 _value,用來保存異步操作的結(jié)果; finale(self);//最后處理這個(gè)promise對(duì)象 }
此時(shí)的promise實(shí)例對(duì)象,關(guān)注對(duì)比p這個(gè)實(shí)例對(duì)象的變化,可以看到resolve之后,相當(dāng)于將異步的結(jié)果給到了p這個(gè)Promise實(shí)例對(duì)象的_value屬性值,同時(shí)改變這個(gè)p的狀態(tài)_state為1 ==> fulfilled
p =>{ _deferredState:1,//deffer的狀態(tài) _state:1,//每個(gè)promise對(duì)象的狀態(tài)維護(hù)標(biāo)識(shí) _value:"someData",//resolve函數(shù)執(zhí)行的時(shí)候,異步得到的結(jié)果 _deferreds: new Handler(onFulfilled, onRejected, res) }2.4 finale(self);//最后處理這個(gè)promise對(duì)象
function finale(self) { //進(jìn)入這個(gè)if語(yǔ)句 if (self._deferredState === 1) { handle(self, self._deferreds); self._deferreds = null; } if (self._deferredState === 2) { for (var i = 0; i < self._deferreds.length; i++) { handle(self, self._deferreds[i]); } self._deferreds = null; } }
function handle(self, deferred) { while (self._state === 3) { self = self._value; } if (Promise._onHandle) { Promise._onHandle(self); } //此時(shí)不會(huì)進(jìn)入這里因?yàn)?_state的值為 1 if (self._state === 0) { if (self._deferredState === 0) { self._deferredState = 1; self._deferreds = deferred; return; } if (self._deferredState === 1) { self._deferredState = 2; self._deferreds = [self._deferreds, deferred]; return; } self._deferreds.push(deferred); return; } //這個(gè)函數(shù)只有當(dāng) _state的值為 1 fulfilled. 2 rejected 的時(shí)候才會(huì)執(zhí)行 handleResolved(self, deferred); }
function handleResolved(self, deferred) { asap(function() { //得到promise.then(function(data){ console.log(data);});注冊(cè)的函數(shù) var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected; if (cb === null) { if (self._state === 1) { resolve(deferred.promise, self._value); } else { reject(deferred.promise, self._value); } return; } //執(zhí)行then中注冊(cè)回調(diào)函數(shù) var ret = tryCallOne(cb, self._value); if (ret === IS_ERROR) { reject(deferred.promise, LAST_ERROR); } else { resolve(deferred.promise, ret); } }); }; function tryCallOne(fn, a) { try { return fn(a); } catch (ex) { LAST_ERROR = ex; return IS_ERROR; } }
至此一個(gè)簡(jiǎn)單的promsie的實(shí)現(xiàn)流程完畢;
下面用實(shí)際的例子來看下:
3 對(duì)于then的鏈?zhǔn)秸{(diào)用,Promise內(nèi)部又是如何運(yùn)行的呢? 下一個(gè)then中注冊(cè)的函數(shù)會(huì)接收到上一個(gè)then的返回值作為該then中注冊(cè)的函數(shù)的參數(shù); 3.1 then注冊(cè)的函數(shù)返回基本數(shù)據(jù)類型function runAsync(){ let p = new Promise(function(resolve,reject){ console.log("exec"); setTimeout(function(){ resolve("someData"); },2000); }); return p; } var promise = runAsync(); promise.then(function(data){ console.log(data); return "someData1" }).then(function(data){ console.log(data); return "someData2" }).then(function(data){ console.log(data) }) console.log("同步執(zhí)行"); console.log(promise);
控制臺(tái)輸出
exec 同步執(zhí)行 Promise //兩秒后 someData someData1 someData2
resolve(deferred.promise, ret);中的ret值就是then中注冊(cè)函數(shù)的返回值,這里就是一些簡(jiǎn)單的字符串"someData1" "someData2"
promise實(shí)例對(duì)象==> 異步成功 ==> 該實(shí)例對(duì)象的resolve(data) ==> //newValue為異步得到的數(shù)據(jù),第一次是"someData"這個(gè)字符串,下一次就是then中注冊(cè)函數(shù)的返回值ret,還是字符串"someData1" "someData2" resolve(self,newValue) ==> <== == == == == == == || ^ ==>handle(self,deffer) || ^ ==>handleResolved處理then中注冊(cè)的函數(shù); || ^ ==>接著處理下一個(gè)promis==>resolve(deferred.promise, ret); ===> ||
var p = { _deferredState:1,//deffer的狀態(tài) _state:0,//每個(gè)promise對(duì)象的狀態(tài)維護(hù)標(biāo)識(shí) _value:null,//resolve函數(shù)執(zhí)行的時(shí)候,異步得到的結(jié)果 _deferreds:{ onFulfilled:onFulfilled, onRejected:onRejected, promise:{//這里是 new Promise(noop) _deferredState:1, _state:0, _value:null, _deferreds:{//通過then注冊(cè)的執(zhí)行對(duì)象 onFulfilled:onFulfilled, onRejected:onRejected, promise:{//這里是 new Promise(noop) _deferredState:1, _state:0, _value:null, _deferreds:{//通過then注冊(cè)的執(zhí)行對(duì)象 onFulfilled:onFulfilled, onRejected:onRejected, promise:{//這里是 new Promise(noop) _deferredState:1 _state:0, _value:null, _deferreds:null }, } } } } } };3.2 then注冊(cè)的函數(shù)返回一個(gè)新的promise
function runAsync(){ let p = new Promise(function(resolve,reject){ console.log("exec"); setTimeout(function(){ resolve("someData"); },2000); }); return p; }; function runAsync1(){ return new Promise(function(resolve,reject){ setTimeout(function(){ resolve("someData1"); },2000); }) }; function runAsync2(){ return new Promise(function(resolve,reject){ setTimeout(function(){ resolve("someData2"); },2000); }) }; //以下的異步操作會(huì)按照順序進(jìn)行執(zhí)行; var promise = runAsync(); promise.then(function(data){ console.log(data); return runAsync1() }).then(function(data){ console.log(data); return runAsync2() }).then(function(data){ console.log(data); // return "someData3" }) console.log("同步執(zhí)行"); console.log(promise);
控制臺(tái)輸出
exec 同步執(zhí)行 Promise //兩秒后 someData //兩秒后 someData1 //兩秒后 someData2
promise實(shí)例對(duì)象 ==> 異步成功 ==> 該實(shí)例對(duì)象的resolve(data) ==> //newValue為異步得到的數(shù)據(jù),這里第一次是 "someData"這個(gè)字符串,下一次就是then中注冊(cè)函數(shù)的返回值,這里就是runAsync返回的promise對(duì)象 resolve(self,newValue) ==> <== == == == == == == || ^ ==>handle(self,deffer) || ^ ==>handleResolved處理then中注冊(cè)的函數(shù); || ^ ==>接著處理下一個(gè)promise==>resolve(deferred.promise, ret); ===> ||
整個(gè)promise鏈如下
var p = { _deferredState:1,//deffer的狀態(tài) _state:0,//每個(gè)promise對(duì)象的狀態(tài)維護(hù)標(biāo)識(shí) _value:null,//resolve函數(shù)執(zhí)行的時(shí)候,異步得到的結(jié)果 _deferreds:{ onFulfilled:onFulfilled, onRejected:onRejected, promise:{ //通過引用的地址改變,這里是runAsync返回的promise _deferredState:1, _state:0, _value:null, _deferreds:{//由于runAsync中沒有執(zhí)行then注冊(cè),這里將new Promise(noop) 通過then注冊(cè)的對(duì)象引用拿到; onFulfilled:onFulfilled, onRejected:onRejected, promise:{//通過引用的地址改變,這里是runAsync返回的promise _deferredState:1, _state:0, _value:null, _deferreds:{ onFulfilled:onFulfilled, onRejected:onRejected, promise:{//通過引用的地址改變,這里是runAsync返回的promise _deferredState:1, _state:0, _value:null, _deferreds:null }, } } } } } }3.3 以上兩者有何差異?
相同點(diǎn):每個(gè)then返回的新的promise對(duì)象是一樣的,都是通過then函數(shù)中的定義的返回值:var res = new Promise(noop);
不同點(diǎn):在handleResolved中,resolve(deferred.promise, ret);中的ret的值不同,ret就是每個(gè)then中注冊(cè)的函數(shù)的返回值,對(duì)比以上兩種情況,一個(gè)返回基本數(shù)據(jù)類型,一個(gè)返回Promise對(duì)象,接下來重點(diǎn)看下then中注冊(cè)的函數(shù)返回promise對(duì)象的情況(注意這個(gè)和then鏈?zhǔn)秸{(diào)用的promise對(duì)象不是一個(gè))
// resolve(deferred.promise, ret);注意這個(gè)self,傳入的是deferred這個(gè)對(duì)象中promise這個(gè)引用地址; //真正調(diào)用這個(gè)函數(shù)的是tryCallTwo中的第二個(gè)函數(shù)入?yún)ⅲ籹elf就是p這個(gè)promise實(shí)例對(duì)象; function resolve(self, newValue) { //此時(shí)的newValue是then中注冊(cè)函數(shù)的返回的Promise實(shí)例對(duì)象 //self是deferred.promise // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure //對(duì)于此時(shí)的案例,不會(huì)進(jìn)入這里 if (newValue === self) { return reject( self, new TypeError("A promise cannot be resolved with itself.") ); } //注意,對(duì)于then中注冊(cè)的函數(shù)返回值是一個(gè)新的promise對(duì)象的時(shí)候,此時(shí)會(huì)進(jìn)入這里 if ( //比如resolve(p1) p1是一個(gè)新的promise對(duì)象; newValue && (typeof newValue === "object" || typeof newValue === "function") ) { var then = getThen(newValue); if (then === IS_ERROR) { return reject(self, LAST_ERROR); } if ( //兩個(gè)Promise對(duì)象原型鏈上都是引用的then這個(gè)函數(shù)地址 then === self.then && newValue instanceof Promise ) { self._state = 3; self._value = newValue; finale(self); //執(zhí)行到這里,結(jié)束; return; } else if (typeof then === "function") { doResolve(then.bind(newValue), self); return; } } //對(duì)于then中注冊(cè)的函數(shù)返回一個(gè)promise對(duì)象的情況,下面就不會(huì)執(zhí)行 self._state = 1; self._value = newValue; finale(self); }
self ==> deferred.promise
function finale(self) { if (self._deferredState === 1) { handle(self, self._deferreds); self._deferreds = null; } if (self._deferredState === 2) { for (var i = 0; i < self._deferreds.length; i++) { handle(self, self._deferreds[i]); } self._deferreds = null; } }
注意在這里通過對(duì)promise鏈進(jìn)行引用的改變,從而使異步的執(zhí)行看起來和同步是一樣的;
handle函數(shù)有兩個(gè)作用,
第一:改變promise鏈的引用,將原本返回的 new Promsie(noop) 改為ret(then中注冊(cè)函數(shù)返回的promise)
第二:將原本new Promsie(noop) 上面通過then注冊(cè)deferred對(duì)象,給到ret響應(yīng)的屬性
function handle(self, deferred) { while (self._state === 3) { //這里一直循環(huán)直到取到我們返回的promsie對(duì)象,也就是上面的ret,即每個(gè)runAsync函數(shù)的返回值; self = self._value; } if (Promise._onHandle) { Promise._onHandle(self); } //將runAsync的返回的promise對(duì)象中_deferredState設(shè)置為 1; if (self._state === 0) { if (self._deferredState === 0) { self._deferredState = 1; self._deferreds = deferred; //執(zhí)行到這里結(jié)束 return; } if (self._deferredState === 1) { self._deferredState = 2; self._deferreds = [self._deferreds, deferred]; return; } self._deferreds.push(deferred); return; } handleResolved(self, deferred); }4 綜合練習(xí)
對(duì)于注釋的代碼可以來回切換,看下結(jié)果。
function runAsync(){ let p = new Promise(function(resolve,reject){ console.log("exec"); setTimeout(function(){ resolve("someData"); },2000); }); return p; }; function runAsync1(){ return new Promise(function(resolve,reject){ setTimeout(function(){ console.log("異步1") // resolve("someData1"); reject("error1") },2000); }) }; function runAsync2(){ return new Promise(function(resolve,reject){ setTimeout(function(){ console.log("異步2") // resolve("someData2"); reject("error2") },2000); }) } var promise = runAsync(); promise.then(function(data){ console.log(data); return runAsync1() }).then(function(data){ console.log(data); return runAsync2() }).then(function(data){ console.log(data); // return "someData3" }).catch(function(error){ console.log(error) }) console.log("同步執(zhí)行"); console.log(promise);
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/92272.html
摘要:雙向數(shù)據(jù)綁定的核心和基礎(chǔ)是其內(nèi)部真正參與數(shù)據(jù)雙向綁定流程的主要有和基于和發(fā)布者訂閱者模式,最終實(shí)現(xiàn)數(shù)據(jù)的雙向綁定。在這里把雙向數(shù)據(jù)綁定分為兩個(gè)流程收集依賴流程依賴收集會(huì)經(jīng)過以上流程,最終數(shù)組中存放列表,數(shù)組中存放列表。 Vue雙向數(shù)據(jù)綁定的核心和基礎(chǔ)api是Object.defineProperty,其內(nèi)部真正參與數(shù)據(jù)雙向綁定流程的主要有Obderver、Dep和Watcher,基于d...
摘要:大家可以看到是構(gòu)造函數(shù)構(gòu)造出來的,并且內(nèi)部有一個(gè)對(duì)象,這個(gè)對(duì)象是本文接下來要重點(diǎn)介紹的對(duì)象,接下來我們就來一窺究竟吧。在構(gòu)造函數(shù)內(nèi)部就進(jìn)行了一步操作,那就是創(chuàng)建了一個(gè)對(duì)象,并掛載到了上。下一篇文章還是流程相關(guān)的內(nèi)容。這是我的剖析 React 源碼的第二篇文章,如果你沒有閱讀過之前的文章,請(qǐng)務(wù)必先閱讀一下 第一篇文章 中提到的一些注意事項(xiàng),能幫助你更好地閱讀源碼。 文章相關(guān)資料 React ...
摘要:就是,如果你不了解這個(gè)的話可以閱讀下相關(guān)文檔,是應(yīng)用初始化時(shí)就會(huì)生成的一個(gè)變量,值也是,并且這個(gè)值不會(huì)在后期再被改變。這是我的剖析 React 源碼的第三篇文章,如果你沒有閱讀過之前的文章,請(qǐng)務(wù)必先閱讀一下 第一篇文章 中提到的一些注意事項(xiàng),能幫助你更好地閱讀源碼。 文章相關(guān)資料 React 16.8.6 源碼中文注釋,這個(gè)鏈接是文章的核心,文中的具體代碼及代碼行數(shù)都是依托于這個(gè)倉(cāng)庫(kù) 熱身...
閱讀 925·2021-11-24 09:38
閱讀 939·2021-11-23 09:51
閱讀 2947·2021-11-16 11:44
閱讀 1775·2021-09-22 15:52
閱讀 1683·2021-09-10 11:20
閱讀 1410·2019-08-30 13:47
閱讀 1304·2019-08-29 12:36
閱讀 3338·2019-08-26 10:43