成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Promise實(shí)現(xiàn)思路的個(gè)人理解

GeekGhc / 2436人閱讀

摘要:不過(guò)最近我對(duì)于實(shí)現(xiàn)的思考過(guò)程的有了一點(diǎn)點(diǎn)個(gè)人理解,特此記下。用例我覺(jué)得實(shí)現(xiàn)一個(gè)函數(shù)跟封裝組件類似,首先從以下幾點(diǎn)考慮這個(gè)函數(shù)用來(lái)做什么的接受哪些參數(shù)返回值是什么那么結(jié)合例子,和這幾個(gè)問(wèn)題,我們得到是做異步流程控制的。

Promise實(shí)現(xiàn)思路的個(gè)人理解

我一直覺(jué)得Promise雖然方便,但是它的寫法很怪,無(wú)法理解實(shí)現(xiàn)Promise的人是如何思考的。

不過(guò)最近我對(duì)于實(shí)現(xiàn)Promise的思考過(guò)程的有了一點(diǎn)點(diǎn)個(gè)人理解,特此記下。

感覺(jué)這篇文章我還是沒(méi)有把思路說(shuō)清楚,時(shí)間緊張,就當(dāng)做一次記錄,回頭我要把這個(gè)過(guò)程在表達(dá)的在清楚一點(diǎn)。

用例
   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"
            } )

我覺(jué)得實(shí)現(xiàn)一個(gè)函數(shù)跟封裝組件類似,首先從以下幾點(diǎn)考慮:

1.這個(gè)函數(shù)用來(lái)做什么的?

2.接受哪些參數(shù)

3.返回值是什么

那么結(jié)合例子,和這幾個(gè)問(wèn)題,我們得到

1.Promise是做異步流程控制的。通俗說(shuō)就是,我希望某個(gè)函數(shù)暫時(shí)不執(zhí)行,等我希望它執(zhí)行時(shí),就resolve一下,你這個(gè)函數(shù)在執(zhí)行。

2.構(gòu)造函數(shù)Promise接受一個(gè)函數(shù)。函數(shù)的參數(shù)是resolve,reject,resolve和reject也是函數(shù),是給用戶調(diào)用用的,當(dāng)用戶希望下一個(gè)異步執(zhí)行時(shí),就調(diào)用resolve(0

3.返回一個(gè)promise實(shí)例。 promise實(shí)例都有一個(gè)then方法,而then方法也返回一個(gè)新的promise實(shí)例。由此就可以鏈?zhǔn)秸{(diào)用then了

先實(shí)現(xiàn)一個(gè)Promise(未實(shí)現(xiàn)then的鏈?zhǔn)秸{(diào)用)

1.Promise接受一個(gè)fn,不管其他,你覺(jué)得這個(gè)fn在內(nèi)部會(huì)干嘛?只能被調(diào)用唄,所以雖然不知道怎么搞,但是先調(diào)用一下fn(resolve,reject)

2.那這個(gè)resolve和reject不是用戶實(shí)現(xiàn)的,所以肯定是Promise開發(fā)者實(shí)現(xiàn)的,那我們要實(shí)現(xiàn)resolve和reject,它們是干嘛的,肯定用來(lái)是改變狀態(tài)的,所以定義this.state

3.resolve和reject也會(huì)接受用戶的參數(shù)吧,那我們就需要把這個(gè)參數(shù)用this.value緩存一下,將來(lái)then方法調(diào)用時(shí),需要傳遞進(jìn)去

4.then接受successFn和errorFn,這2個(gè)就是我們希望暫時(shí)不執(zhí)行的函數(shù)了。怎么做到暫時(shí)不執(zhí)行呢?就是聲明2個(gè)數(shù)組,把他們先存起來(lái),將來(lái)resolve時(shí),在調(diào)用

        class Promise2 {
            constructor( fn ) {
                this.successFnArray = []  // 用來(lái)緩存successFn和errorFn
                this.errorFnArray = []
                this.state = "pendding"
                const resolve = ( res ) => {      // resolve就做2件事情  1: 修改狀態(tài) 2:調(diào)用successFn
                    this.state = "fulfilled"
                    this.value = res         // this.value用來(lái)緩存data數(shù)據(jù)或者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 )   // 先調(diào)用fn再說(shuō)
            }

            then( successFn, errorFn ) {
                switch ( this.state ) {
                    case "fulfilled":
                        successFn( this.value )        // 如果調(diào)用了resolve,狀態(tài)就成了fulfilled,就會(huì)執(zhí)行successFn
                        break
                    case "rejected":
                        errorFn( this.value )
                        break
                    case "pendding":
                        this.successFnArray.push( successFn )   // 如果還沒(méi)調(diào)用resolve,狀態(tài)就是pendding,就先把這些異步函數(shù)緩存起來(lái)。將來(lái)resole時(shí)調(diào)用
                        this.errorFnArray.push( errorFn )
                }
            }
        }

        var p1 = new Promise2( ( resolve, reject ) => {
            setTimeout( () => {
                resolve( "hello" )
            }, 1000 )

        } )

        p1.then( res => {
            console.log( res + "world" )
            return res + "world"
        } )
實(shí)現(xiàn)then鏈?zhǔn)秸{(diào)用

then的實(shí)現(xiàn),和JQ的鏈?zhǔn)秸{(diào)用不同,JQ是每次調(diào)用方法后,把this返回

而Promise規(guī)范要求,每次都要返回新的Promise對(duì)象

所以只需要把then方法修改一下。

這部分可能會(huì)迷惑,但是我想先說(shuō)一下這里做了哪些事情,其實(shí)變化不大

之前的then做了哪些事情?

就是按照不同的state,調(diào)用了successFn或者errorFn,如果是pendding狀態(tài)就先緩存起來(lái),等將來(lái)resolve時(shí)調(diào)用

鏈?zhǔn)絫hen有哪些改動(dòng)?

首先then有了返回值,返回一個(gè)promise,而之前沒(méi)有返回值,return的是undefined

new Promise的過(guò)程,其實(shí)邏輯沒(méi)什么變化,唯一注意的,比如狀態(tài)fulfilled時(shí),并非直接調(diào)用successFn

而是調(diào)用_successFn,而這個(gè)函數(shù)內(nèi)部本質(zhì)上還是調(diào)用successFn(),但同時(shí)把調(diào)用的返回值作為了resolve的參數(shù),調(diào)用了resolve()

因?yàn)楫?dāng)successFn被調(diào)用,得到返回值時(shí),就表示這個(gè)函數(shù)執(zhí)行完了,

就需要執(zhí)行下一個(gè)異步函數(shù)了,這樣下一個(gè)異步函數(shù)也會(huì)把successFn(res)的return值作為參數(shù)

       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 )
                    }
                } )

            }

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/99325.html

相關(guān)文章

  • 徹底理解Promise對(duì)象——用es5語(yǔ)法實(shí)現(xiàn)一個(gè)自己Promise(上篇)

    摘要:鏈?zhǔn)秸{(diào)用在的使用中,我們一定注意到,是可以鏈?zhǔn)秸{(diào)用的很顯然,要實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用,方法的返回值也必須是一個(gè)對(duì)象,這樣才能再次在后面調(diào)用。一種情況下,前一個(gè)的或者的返回值是普通的對(duì)象,這種情況下我們目前的可以正確處理。 本文同步自我的個(gè)人博客: http://mly-zju.github.io/ 眾所周知javascript語(yǔ)言的一大特色就是異步,這既是它的優(yōu)點(diǎn),同時(shí)在某些情況下也帶來(lái)了一些的...

    YJNldm 評(píng)論0 收藏0
  • Promise源碼學(xué)習(xí)(1)

    摘要:工作當(dāng)中經(jīng)常會(huì)用到,在此進(jìn)行深入學(xué)習(xí)異步編程解決方案是異步編程的一種解決方案,比傳統(tǒng)的解決方案回調(diào)函數(shù)和事件更合理和更強(qiáng)大。所有源碼注釋見(jiàn)學(xué)習(xí)筆記 工作當(dāng)中經(jīng)常會(huì)用到Promise,在此進(jìn)行深入學(xué)習(xí) 異步編程解決方案 Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強(qiáng)大。它由社區(qū)最早提出和實(shí)現(xiàn),ES6 將其寫進(jìn)了語(yǔ)言標(biāo)準(zhǔn),統(tǒng)一了用法,原生提供了...

    young.li 評(píng)論0 收藏0
  • co源碼分析及其實(shí)踐

    摘要:返回的結(jié)果是一個(gè)對(duì)象,類似于表示本次后面執(zhí)行之后返回的結(jié)果。對(duì)象用于一個(gè)異步操作的最終完成或失敗及其結(jié)果值的表示簡(jiǎn)單點(diǎn)說(shuō)就是處理異步請(qǐng)求。源碼分析主要脈絡(luò)函數(shù)調(diào)用后,返回一個(gè)實(shí)例。參考鏈接解釋對(duì)象的用法的源碼及其用法 本文始發(fā)于我的個(gè)人博客,如需轉(zhuǎn)載請(qǐng)注明出處。為了更好的閱讀體驗(yàn),可以直接進(jìn)去我的個(gè)人博客看。 前言 知識(shí)儲(chǔ)備 閱讀本文需要對(duì)Generator和Promise有一個(gè)基本的...

    vincent_xyb 評(píng)論0 收藏0
  • 「今日頭條」前端面試題和思路解析

    摘要:一篇文章和一道面試題最近,有篇名為張圖幫你一步步看清和的執(zhí)行順序的文章引起了我的關(guān)注。作者用一道年今日頭條的前端面試題為引子,分步講解了最終結(jié)果的執(zhí)行原因。從字面意思理解,讓我們等等。當(dāng)前的最新版本,在這里的執(zhí)行順序上,的確存在有問(wèn)題。 一篇文章和一道面試題 最近,有篇名為 《8張圖幫你一步步看清 async/await 和 promise 的執(zhí)行順序》 的文章引起了我的關(guān)注。 作者用...

    寵來(lái)也 評(píng)論0 收藏0
  • 理解javascript中事件循環(huán)(Event Loop)

    摘要:主線程會(huì)暫時(shí)存儲(chǔ)等異步操作,直接向下執(zhí)行,當(dāng)某個(gè)異步事件觸發(fā)時(shí),再通知主線程執(zhí)行相應(yīng)的回調(diào)函數(shù),通過(guò)這種機(jī)制,避免了單線程中異步操作耗時(shí)對(duì)后續(xù)任務(wù)的影響。 背景 在研究js的異步的實(shí)現(xiàn)方式的時(shí)候,發(fā)現(xiàn)了JavaScript 中的 macrotask 和 microtask 的概念。在查閱了一番資料之后,對(duì)其中的執(zhí)行機(jī)制有所了解,下面整理出來(lái),希望可以幫助更多人。 先了解一下js的任務(wù)執(zhí)...

    mykurisu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<