摘要:不過最近我對于實現的思考過程的有了一點點個人理解,特此記下。用例我覺得實現一個函數跟封裝組件類似,首先從以下幾點考慮這個函數用來做什么的接受哪些參數返回值是什么那么結合例子,和這幾個問題,我們得到是做異步流程控制的。
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 ) } } ) }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/99325.html
摘要:鏈式調用在的使用中,我們一定注意到,是可以鏈式調用的很顯然,要實現鏈式調用,方法的返回值也必須是一個對象,這樣才能再次在后面調用。一種情況下,前一個的或者的返回值是普通的對象,這種情況下我們目前的可以正確處理。 本文同步自我的個人博客: http://mly-zju.github.io/ 眾所周知javascript語言的一大特色就是異步,這既是它的優點,同時在某些情況下也帶來了一些的...
摘要:工作當中經常會用到,在此進行深入學習異步編程解決方案是異步編程的一種解決方案,比傳統的解決方案回調函數和事件更合理和更強大。所有源碼注釋見學習筆記 工作當中經常會用到Promise,在此進行深入學習 異步編程解決方案 Promise 是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和更強大。它由社區最早提出和實現,ES6 將其寫進了語言標準,統一了用法,原生提供了...
摘要:返回的結果是一個對象,類似于表示本次后面執行之后返回的結果。對象用于一個異步操作的最終完成或失敗及其結果值的表示簡單點說就是處理異步請求。源碼分析主要脈絡函數調用后,返回一個實例。參考鏈接解釋對象的用法的源碼及其用法 本文始發于我的個人博客,如需轉載請注明出處。為了更好的閱讀體驗,可以直接進去我的個人博客看。 前言 知識儲備 閱讀本文需要對Generator和Promise有一個基本的...
摘要:一篇文章和一道面試題最近,有篇名為張圖幫你一步步看清和的執行順序的文章引起了我的關注。作者用一道年今日頭條的前端面試題為引子,分步講解了最終結果的執行原因。從字面意思理解,讓我們等等。當前的最新版本,在這里的執行順序上,的確存在有問題。 一篇文章和一道面試題 最近,有篇名為 《8張圖幫你一步步看清 async/await 和 promise 的執行順序》 的文章引起了我的關注。 作者用...
摘要:主線程會暫時存儲等異步操作,直接向下執行,當某個異步事件觸發時,再通知主線程執行相應的回調函數,通過這種機制,避免了單線程中異步操作耗時對后續任務的影響。 背景 在研究js的異步的實現方式的時候,發現了JavaScript 中的 macrotask 和 microtask 的概念。在查閱了一番資料之后,對其中的執行機制有所了解,下面整理出來,希望可以幫助更多人。 先了解一下js的任務執...
閱讀 1017·2021-10-27 14:15
閱讀 2773·2021-10-25 09:45
閱讀 1938·2021-09-02 09:45
閱讀 3363·2019-08-30 15:55
閱讀 1806·2019-08-29 16:05
閱讀 3199·2019-08-28 18:13
閱讀 3112·2019-08-26 13:58
閱讀 448·2019-08-26 12:01