這篇文章帶給大家的內容是關於Promise實現思路的深入分析(程式碼範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
Promise實現想法的個人理解
我一直覺得Promise雖然方便,但是它的寫法很怪,無法理解實現Promise的人是如何思考的。
不過最近我對於實現Promise的思考過程的有了一點點個人理解,特此記下。
感覺這篇文章我還是沒有把思路說清楚,時間緊張,就當做一次記錄,回頭我要把這個過程在表達的在清楚一點。
用例
var p1 = new Promise2( ( resolve, reject ) => { setTimeout( () => { resolve( 'hello' ) }, 1000 ) } ) p1.then( res => { console.log( res + 'world' ) return res + 'world' } ) .then( res => { console.log( res + 'ziwei' ) return res + 'ziwei' } )
我覺得實作一個函數跟封裝元件類似,首先從以下幾點考慮:
1 .這個函數用來做什麼的?
2.接受哪些參數
3.傳回值是什麼
那麼結合例子,和這幾個問題,我們得到
1.Promise是做非同步流程控制的。 通俗說就是,我希望某個函數暫時不執行,等我希望它執行時,就resolve一下,你這個函數在執行。
2.建構子Promise接受一個函式。 函數的參數是resolve,reject,resolve和reject也是函數,是給使用者呼叫用的,當使用者希望下一個非同步執行時,就呼叫resolve(0
# 3.傳回一個promise實例。 promise實例都有一個then方法,而then方法也傳回一個新的promise實例。由此就可以鍊式呼叫then了
#先實作一個Promise(未實作then的鍊式呼叫)
#1.Promise接受一個fn,不管其他,你覺得這個fn在內部會幹嘛?只能被呼叫唄,所以雖然不知道怎麼搞,但是先呼叫一下fn(resolve,reject)
2.那這個resolve和reject不是用戶實現的,所以肯定是Promise開發者實現的,那我們要實作resolve和reject,它們是乾嘛的,一定用來是改變狀態的,所以定義this.state
3.resolve和reject也會接受使用者的參數吧,那我們就需要把這個參數用this.value快取一下,將來then方法呼叫時,需要傳遞進去
4.then接受successFn和errorFn,這2個就是我們希望暫時不執行的函數了。怎麼做到暫時不執行呢?就是宣告2個數組,把他們先存起來,將來resolve時,在呼叫
class Promise2 { constructor( fn ) { this.successFnArray = [] // 用来缓存successFn和errorFn this.errorFnArray = [] this.state = 'pendding' const resolve = ( res ) => { // resolve就做2件事情 1: 修改状态 2:调用successFn this.state = 'fulfilled' this.value = res // this.value用来缓存data数据或者error this.successFnArray.forEach( successFn => { successFn( res ) } ) } const reject = ( err ) => { this.state = 'rejected' this.value = err this.errorFnArray.forEach( errorFn => { errorFn( res ) } ) } fn( resolve, reject ) // 先调用fn再说 } then( successFn, errorFn ) { switch ( this.state ) { case 'fulfilled': successFn( this.value ) // 如果调用了resolve,状态就成了fulfilled,就会执行successFn break case 'rejected': errorFn( this.value ) break case 'pendding': this.successFnArray.push( successFn ) // 如果还没调用resolve,状态就是pendding,就先把这些异步函数缓存起来。将来resole时调用 this.errorFnArray.push( errorFn ) } } } var p1 = new Promise2( ( resolve, reject ) => { setTimeout( () => { resolve( 'hello' ) }, 1000 ) } ) p1.then( res => { console.log( res + 'world' ) return res + 'world' } )
實作then鍊式呼叫
then的實現,和JQ的鍊式呼叫不同,JQ是每次呼叫方法後,把this回傳
而Promise規範要求,每次都要返回新的Promise物件
所以只需要把then方法修改一下。
這部分可能會迷惑,但是我想先說一下這裡做了哪些事情,其實變化不大
之前的then做了哪些事情?
就是依照不同的state,呼叫了successFn或errorFn,如果是pendding狀態就先緩存起來,等將來resolve時呼叫
鍊式then有哪些改動?
首先then有了回傳值,回傳一個promise,而之前沒有回傳值,return的是undefined
new Promise的過程,其實邏輯沒什麼變化,唯一注意的,例如狀態fulfilled時,並非直接呼叫successFn
#而是呼叫_successFn,而這個函數內部本質上還是呼叫successFn(),但同時把呼叫的回傳值當作了resolve的參數,呼叫了resolve()
#因為當successFn被調用,得到返回值時,就表示這個函數執行完了,
就需要執行下一個非同步函數了,這樣下一個非同步函數也會把successFn(res)的return值當作參數
then( successFn, errorFn ) { return new Promise2( ( resolve, reject ) => { const _successFn = res => { resolve(successFn(res)) } const _errorFn = err => { reject(errorFn(err)) } switch ( this.state ) { case 'fulfilled': _successFn( this.value ) break case 'rejected': _errorFn( this.value ) break case 'pendding': this.successFnArray.push( _successFn ) this.errorFnArray.push( _errorFn ) } } ) }
以上是Promise實現想法的深入分析(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!