原文連接:連接javascript
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('同步執行'); console.log(promise);
控制檯輸出java
exec 同步執行 Promise //兩秒後 someData
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這個函數,那麼不會執行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. 函數不是noop的時候,git
p =>{ _deferredState:0,//deffer的狀態,表明的應該是 _deferreds 的類型,1 是 single,2 是 Array _state:0,//每一個promise對象的狀態維護標識 _value:null,//resolve函數執行的時候,異步獲得的結果 _deferreds:null }
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的鏈式調用,每次then函數執行完畢以後,返回值都是一個新的Promise實例對象, return res; }; //這裏生成一個deffer對象,保存then函數中註冊的onFulfilled和onRejected回調,以及要返回的新的promise實例對象 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) { //不會進入這裏 while (self._state === 3) { self = self._value; } //也不會進入這裏 if (Promise._onHandle) { Promise._onHandle(self); } //進入這裏,注意這裏,若是經過then的鏈式調用,那麼每次then返回的對象都是一個新的相似於下面 p 實例對象; 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; } //這個函數只有當 _state的值爲 1 2的時候纔會執行 handleResolved(self, deferred); }
此時再來看下p這個promise實例的屬性值github
p =>{ _deferredState:1,//deffer的狀態 _state:0,//每一個promise對象的狀態維護標識 _value:null,//resolve函數執行的時候,異步獲得的結果 _deferreds: new Handler(onFulfilled, onRejected, res)//存放經過then註冊的函數以及返回的❤️Promise實例對象的一個Handler對象; } res:{ _deferredState:0,//deffereds的狀態, _state:0,//每一個promise對象的狀態維護標識 _value:null,//resolve函數執行的時候,異步獲得的結果 _deferreds:null }
若是返回的res在執行then方法,那麼c#
p =>{ _deferredState:1,//deffer的狀態 _state:0,//每一個promise對象的狀態維護標識 _value:null,//resolve函數執行的時候,異步獲得的結果 _deferreds: new Handler(onFulfilled, onRejected, res)//存放經過then註冊的函數以及返回的❤️Promise實例對象的一個Handler對象; } res:{ _deferredState:1,//deffereds的狀態, _state:0,//每一個promise對象的狀態維護標識 _value:null,//resolve函數執行的時候,異步獲得的結果 _deferreds:new Handler(onFulfilled, onRejected, res)//存放經過then註冊的函數以及返回的❤️Promise實例對象的一個Handler對象; }
//真正調用這個函數的是tryCallTwo中的第二個函數入參;self就是p這個promise實例對象; function resolve(self, newValue) { // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure //對於此時的案例,不會進入這裏 if (newValue === self) { return reject( self, new TypeError('A promise cannot be resolved with itself.') ); } //也不會進入這裏 if ( //好比resolve(p1) p1是一個新的promise對象; 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; } } //對於簡單的返回值,好比後臺返回的JSON字符串等,這裏就直接進行處理; self._state = 1;//fulfilled self._value = newValue;//給這個promise對象添加屬性值 _value,用來保存異步操做的結果; finale(self);//最後處理這個promise對象 }
此時的promise實例對象,關注對比p這個實例對象的變化,能夠看到resolve以後,至關於將異步的結果給到了p這個Promise實例對象的_value
屬性值,同時改變這個p的狀態_state
爲1 ==> fulfilledpromise
p =>{ _deferredState:1,//deffer的狀態 _state:1,//每一個promise對象的狀態維護標識 _value:'someData',//resolve函數執行的時候,異步獲得的結果 _deferreds: new Handler(onFulfilled, onRejected, res) }
function finale(self) { //進入這個if語句 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); } //此時不會進入這裏由於 _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; } //這個函數只有當 _state的值爲 1 fulfilled. 2 rejected 的時候纔會執行 handleResolved(self, deferred); }
function handleResolved(self, deferred) { asap(function() { //獲得promise.then(function(data){ console.log(data);});註冊的函數 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; } //執行then中註冊回調函數 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; } }
至此一個簡單的promsie的實現流程完畢;異步
下面用實際的例子來看下:函數
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('同步執行'); console.log(promise);
控制檯輸出oop
exec 同步執行 Promise //兩秒後 someData someData1 someData2
resolve(deferred.promise, ret);中的ret值就是then中註冊函數的返回值,這裏就是一些簡單的字符串'someData1' 'someData2'this
promise實例對象==> 異步成功 ==> 該實例對象的resolve(data) ==> //newValue爲異步獲得的數據,第一次是'someData'這個字符串,下一次就是then中註冊函數的返回值ret,仍是字符串'someData1' 'someData2' resolve(self,newValue) ==> <== == == == == == == || ^ ==>handle(self,deffer) || ^ ==>handleResolved處理then中註冊的函數; || ^ ==>接着處理下一個promis==>resolve(deferred.promise, ret); ===> ||
var p = { _deferredState:1,//deffer的狀態 _state:0,//每一個promise對象的狀態維護標識 _value:null,//resolve函數執行的時候,異步獲得的結果 _deferreds:{ onFulfilled:onFulfilled, onRejected:onRejected, promise:{//這裏是 new Promise(noop) _deferredState:1, _state:0, _value:null, _deferreds:{//經過then註冊的執行對象 onFulfilled:onFulfilled, onRejected:onRejected, promise:{//這裏是 new Promise(noop) _deferredState:1, _state:0, _value:null, _deferreds:{//經過then註冊的執行對象 onFulfilled:onFulfilled, onRejected:onRejected, promise:{//這裏是 new Promise(noop) _deferredState:1 _state:0, _value:null, _deferreds:null }, } } } } } };
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); }) }; //如下的異步操做會按照順序進行執行; 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('同步執行'); console.log(promise);
控制檯輸出
exec 同步執行 Promise //兩秒後 someData //兩秒後 someData1 //兩秒後 someData2
promise實例對象 ==> 異步成功 ==> 該實例對象的resolve(data) ==> //newValue爲異步獲得的數據,這裏第一次是 'someData'這個字符串,下一次就是then中註冊函數的返回值,這裏就是runAsync返回的promise對象 resolve(self,newValue) ==> <== == == == == == == || ^ ==>handle(self,deffer) || ^ ==>handleResolved處理then中註冊的函數; || ^ ==>接着處理下一個promise==>resolve(deferred.promise, ret); ===> ||
整個promise鏈以下
var p = { _deferredState:1,//deffer的狀態 _state:0,//每一個promise對象的狀態維護標識 _value:null,//resolve函數執行的時候,異步獲得的結果 _deferreds:{ onFulfilled:onFulfilled, onRejected:onRejected, promise:{ //經過引用的地址改變,這裏是runAsync返回的promise _deferredState:1, _state:0, _value:null, _deferreds:{//因爲runAsync中沒有執行then註冊,這裏將new Promise(noop) 經過then註冊的對象引用拿到; 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 }, } } } } } }
// resolve(deferred.promise, ret);注意這個self,傳入的是deferred這個對象中promise這個引用地址; //真正調用這個函數的是tryCallTwo中的第二個函數入參;self就是p這個promise實例對象; function resolve(self, newValue) { //此時的newValue是then中註冊函數的返回的Promise實例對象 //self是deferred.promise // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure //對於此時的案例,不會進入這裏 if (newValue === self) { return reject( self, new TypeError('A promise cannot be resolved with itself.') ); } //注意,對於then中註冊的函數返回值是一個新的promise對象的時候,此時會進入這裏 if ( //好比resolve(p1) p1是一個新的promise對象; newValue && (typeof newValue === 'object' || typeof newValue === 'function') ) { var then = getThen(newValue); if (then === IS_ERROR) { return reject(self, LAST_ERROR); } if ( //兩個Promise對象原型鏈上都是引用的then這個函數地址 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; } } //對於then中註冊的函數返回一個promise對象的狀況,下面就不會執行 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; } }
注意在這裏經過對promise鏈進行引用的改變,從而使異步的執行看起來和同步是同樣的;
handle函數有兩個做用,
function handle(self, deferred) { while (self._state === 3) { //這裏一直循環直到取到咱們返回的promsie對象,也就是上面的ret,即每一個runAsync函數的返回值; self = self._value; } if (Promise._onHandle) { Promise._onHandle(self); } //將runAsync的返回的promise對象中_deferredState設置爲 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; } handleResolved(self, deferred); }
對於註釋的代碼能夠來回切換,看下結果。
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('同步執行'); console.log(promise);