国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

切圖崽的自我修養(yǎng)-[ES6] 異步函數(shù)管理方案淺析

jzman / 2961人閱讀

摘要:前言業(yè)務(wù)開發(fā)中經(jīng)常會(huì)用到異步函數(shù),這里簡單的對(duì)異步函數(shù)以及它的各種各樣的解決方案做一個(gè)淺析優(yōu)缺點(diǎn)優(yōu)點(diǎn)能夠極大的提高程序并發(fā)業(yè)務(wù)邏輯的能力缺點(diǎn)異步函數(shù)的書寫方式和代碼執(zhí)行邏輯很不直觀,回調(diào)函數(shù)這種方式不太符合人類的的線性思維異步函數(shù)的執(zhí)行流程

前言

業(yè)務(wù)開發(fā)中經(jīng)常會(huì)用到異步函數(shù),這里簡單的對(duì)異步函數(shù)以及它的各種各樣的解決方案做一個(gè)淺析

優(yōu)缺點(diǎn):

優(yōu)點(diǎn):

能夠極大的提高程序并發(fā)業(yè)務(wù)邏輯的能力.

缺點(diǎn):

異步函數(shù)的書寫方式和代碼執(zhí)行邏輯很不直觀,回調(diào)函數(shù)這種方式不太符合人類的的線性思維

異步函數(shù)的執(zhí)行流程通常不好管理

不好對(duì)異步函數(shù)部署錯(cuò)誤處理機(jī)制


解決方案

針對(duì)異步函數(shù)存在的缺點(diǎn),所以才有了形形色色的異步的處理方案,常見的比如

原生的回調(diào)函數(shù)

promise/A+

async/await(generator);


業(yè)務(wù)場景

但這些解決方案各自能解決什么問題,才是我們所關(guān)心的.
實(shí)際上,如果對(duì)業(yè)務(wù)場景進(jìn)行抽象,開發(fā)過程中對(duì)異步函數(shù)的管理可以抽象成如下的幾種需求
比如有異步函數(shù)f1,f2,f3:

對(duì)f1,f2,f3之間的執(zhí)行順序沒有要求. 它們的執(zhí)行結(jié)果不互相依賴,誰先完成誰后完成無關(guān)緊要

對(duì)f1,f2,f3之間的執(zhí)行順序沒有要求. 它們的執(zhí)行結(jié)果不互相依賴,誰先完成誰后完成無關(guān)緊要. 但有一個(gè)函數(shù)f4,它必須等到f1,f2,f3執(zhí)行完畢之后才能執(zhí)行

對(duì)f1,f2,f3之間的執(zhí)行順序有要求,必須要滿足f1->f2->f3的執(zhí)行順序

下面就來簡單介紹一下,各個(gè)解決方案針對(duì)不同的業(yè)務(wù)場景,能解決什么問題


需求1

對(duì)f1,f2,f3執(zhí)行完成的順序沒有要求,即它們的執(zhí)行結(jié)果是不互相依賴的,我們可以寫成如下的形式

    f1(function(){});
    f2(function(){});
    f3(function(){});
    ...
    

需求2

f1,f2,f3之間執(zhí)行完成的順序沒有要求,即它們各自的執(zhí)行結(jié)果是不互相依賴的,但有一個(gè)函數(shù)f4,需要等f1,f2,f3函數(shù)全部執(zhí)行完成之后才能執(zhí)行

解決方法:`維護(hù)一個(gè)記數(shù)器`. f1,f2,f3的執(zhí)行順序無關(guān)緊要,但對(duì)于f1,f2,f3每一個(gè)完成的回調(diào)里,都要判斷是否3個(gè)函數(shù)都已完成(通過count來判斷),如果都已完成,則執(zhí)行f4.  Ps(這里的寫成自執(zhí)行的形式是防止count被污染)  實(shí)際上,node的三方異步管理模塊EventProxy, 以及promise的promise.all的實(shí)現(xiàn),都是采用這種方式來對(duì)異步函數(shù)進(jìn)行管理的.

    (function(){
        let count = 0;
        function handler(){
            if(count==3){
                f4();
            }
        }
        
        f1(function(){count++; handler();});
        f2(function(){count++; handler();});
        f3(function(){count++; handler();});
    }()

需求3

對(duì)于異步函數(shù)f1,f2,f3,我想保證它們的執(zhí)行順序是f1->f2->f3的順序(即f1如果執(zhí)行成功,調(diào)用f2,如果f2執(zhí)行成功,調(diào)用f3)

3.1

按最原始的方法,可以寫成如下回調(diào)嵌套的形式.即把f2作為f1的回調(diào),f3作為f3的回調(diào).依次嵌套就可以滿足f1->f2->f3這種調(diào)用形式. 這種方法雖然能夠滿足需求但同時(shí)存在很多問題: 回調(diào)層級(jí)太深不好調(diào)試.

最簡單的情況,假設(shè)不考慮f1,f2,f3出錯(cuò)的情況(即f1,f2,f3全部都執(zhí)行正確),函數(shù)的執(zhí)行流程大概是這樣:

    
    f1(function(){
        f2(function(){
            f3(function(){
                ...
            })
        })
    })

實(shí)際上,考慮到各個(gè)異步函數(shù)都有可能出錯(cuò)的分支, 真實(shí)的執(zhí)行流程應(yīng)該是這樣(這才三層回調(diào)嵌套,代碼已經(jīng)完全混亂的不能看了):


    f1(function(){
        if(err){
            //f1 err handler
        }
        else{
            f2(function(){
                if(err){
                    //f2 err handler    
                }
                
                else{
                    f3(function(){
                        if(err){
                            //f2 err handler
                        }
                        else{
                            ...
                        }
                    })    
                }
            
            })
        }
    })
    
        
3.2

為了解決這個(gè)嵌套過深這種問題,所以有了promise這種的解決方案. 這種規(guī)則邏輯比較清晰,更容易理解,但需要做一點(diǎn)點(diǎn)預(yù)備工作. 即異步函數(shù)f1,f2,f3全部要先封裝成promise規(guī)范,這里拿f1舉例(f2,f3同理).

   function f1(){
           var promiseObj = new Promise(function(resolve,reject){
            //f1的具體功能代碼實(shí)現(xiàn)
            ...
            
            if(f1err){ //如果f1執(zhí)行出錯(cuò)
                reject(failValue);
            }
            else{ //如果f1執(zhí)行成功
                resolve(successValue);
            }
           })
           return promiseObj;
   }
   

預(yù)備工作做完了,我們來看具體實(shí)現(xiàn)

    f1()
    .then(function suc(){return f2()},function fail(){/*f1 err handler*/})
    .then(function suc(){return f3()},function fail(){/*f2 err handler*/})
    .then(function suc(){},function fail(){/*f3 err handler*/})

簡單來分析下,首先f1()執(zhí)行完成后,會(huì)返回一個(gè)promise對(duì)象,它會(huì)被then捕獲,如果promise對(duì)象的狀態(tài)是resolve狀態(tài),會(huì)調(diào)用then的第一個(gè)參數(shù),即成功回調(diào). 如果promise對(duì)象的狀態(tài)是reject狀態(tài),會(huì)調(diào)用then的第二個(gè)參數(shù),即失敗回調(diào).

如果f1執(zhí)行成功,則會(huì)在then中的成功回調(diào)suc中調(diào)用f2(),而f2()返回的也是一個(gè)promise對(duì)象,會(huì)被下一個(gè)then捕獲...依次類推

如果f1執(zhí)行失敗,會(huì)在then的失敗回調(diào)fail中調(diào)用你寫的err handler句柄,然后return跳出整個(gè)執(zhí)行鏈就可以

我們可以看到promise的語法實(shí)際上是將深度嵌套的邏輯通過then的處理平攤了.在這種語法規(guī)則下,f1->f2->f3的執(zhí)行順序一目了然.當(dāng)然它還是有缺點(diǎn)的,就像之前提到的,它必須要做一些預(yù)備工作,即需要把異步函數(shù)要封裝成promise規(guī)范. 另外,它還有一堆then,看起來有點(diǎn)頭暈

3.3

既然promise我們也覺得有點(diǎn)麻煩,那只能試試es7的async/await了,聽說async/await+promise是管理異步回調(diào)的終極解決方案

首先來明晰下try/catch的概念. 當(dāng)一個(gè)代碼片段,我們不能確定它到底能不能成功執(zhí)行的情況下,就會(huì)用try/catch處理. 當(dāng)fun函數(shù)自上到下執(zhí)行,一開始會(huì)進(jìn)入try{}塊,開始執(zhí)行這個(gè)代碼片段

一旦try{}塊內(nèi)部某一條代碼沒有正確執(zhí)行,則不再執(zhí)行try{}塊內(nèi)部的代碼,而是立馬跳出try{}塊,同時(shí)會(huì)拋出一個(gè)異常,這個(gè)異常會(huì)被catch(){}捕獲. 開始執(zhí)行catch{}塊里的代碼. 我們假設(shè)code2出錯(cuò)了,整個(gè)函數(shù)內(nèi)部的執(zhí)行順序是 code 0 -> code 1 -> code 2-> code 4 -> code 5;

如果try{}塊內(nèi)部的代碼片段全都正確執(zhí)行了.就不會(huì)進(jìn)入catch{}的錯(cuò)誤處理流程了. 這時(shí)候整個(gè)函數(shù)內(nèi)部的執(zhí)行順序是 code 0 -> code 1 -> code 2-> code 3 -> code 5;

  
  
          functionfun(){
            
                /* code 0 */

            
                try{
                    /* code 1 */
                    /* code 2 */
                    /* code 3 */                
                }
                catch(err){
                    /* code 4 */
                }
                
                /* code 5 */

            }
            
            fun();
            
            

對(duì)應(yīng)到async上也是同理,async函數(shù)有一個(gè)特點(diǎn),它的await能監(jiān)聽一個(gè)promise對(duì)象. 如果監(jiān)聽到的promise對(duì)象是resolve正確態(tài),那么await這條語句相當(dāng)于是被正確執(zhí)行了,不會(huì)進(jìn)入catch{}流程. 但如果監(jiān)聽到的promise是reject錯(cuò)誤態(tài),則會(huì)認(rèn)為await語句執(zhí)行失敗了,會(huì)拋出異常然后跳進(jìn)catch{}錯(cuò)誤處理.

    var funa = function(){
        var promiseObj_a = new Promise(function(resolve,reject){
            setTimeout(function(){resolve(1);},1000);
        });
        return promiseObj_a;
    }
    var funb = function(){
        var promiseObj_b = new Promise(function(resolve,reject){
            setTimeout(function(){resolve(2);},5000)
        });
        return promiseObj_b;
    }
    var func = function(){
        var promiseObj_c = new Promise(function(resolve,reject){
            setTimeout(function(){reject(3);},8000);
        });
        return promiseObj_c;
    }
    
    async function testAsync(){
        
        try {
            var a =await funa();
            console.log(a,"resolve");
        }
        catch(erra){
            console.log(erra,"reject");
        }
        
        try {
            var b =await funb();
            console.log(b,"resolve");
        }
        catch(errb){
            console.log(errb,"reject");
        }
    
        try {
            var c =await func();
            console.log(c,"resolve");
        }
        catch(errc){
            console.log(errc,"reject");
        }
    }
    
    testAsync();
    //輸出結(jié)果是 
    //1 resolve
    //2 resolve
    //3 reject
    

我們能看到async/await配合promise帶來了巨大的好處. 首先異步函數(shù)的執(zhí)行順序能夠像同步一樣一眼看出來,簡單明了. 其次,針對(duì)任何一個(gè)異步函數(shù)的執(zhí)行,都有完善的try/catch機(jī)制,錯(cuò)誤處理非常非常容易.

結(jié)言

各種解決方案需要結(jié)合對(duì)應(yīng)的業(yè)務(wù)場景使用

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/50013.html

相關(guān)文章

  • 切圖崽的自我修養(yǎng)-[ES6] 異步函數(shù)管理方案淺析

    摘要:前言業(yè)務(wù)開發(fā)中經(jīng)常會(huì)用到異步函數(shù),這里簡單的對(duì)異步函數(shù)以及它的各種各樣的解決方案做一個(gè)淺析優(yōu)缺點(diǎn)優(yōu)點(diǎn)能夠極大的提高程序并發(fā)業(yè)務(wù)邏輯的能力缺點(diǎn)異步函數(shù)的書寫方式和代碼執(zhí)行邏輯很不直觀,回調(diào)函數(shù)這種方式不太符合人類的的線性思維異步函數(shù)的執(zhí)行流程 前言 業(yè)務(wù)開發(fā)中經(jīng)常會(huì)用到異步函數(shù),這里簡單的對(duì)異步函數(shù)以及它的各種各樣的解決方案做一個(gè)淺析 優(yōu)缺點(diǎn): 優(yōu)點(diǎn): 能夠極大的提高程序并發(fā)業(yè)務(wù)邏輯的能...

    KavenFan 評(píng)論0 收藏0
  • 切圖崽的自我修養(yǎng)-[ES6] 異步函數(shù)管理方案淺析

    摘要:前言業(yè)務(wù)開發(fā)中經(jīng)常會(huì)用到異步函數(shù),這里簡單的對(duì)異步函數(shù)以及它的各種各樣的解決方案做一個(gè)淺析優(yōu)缺點(diǎn)優(yōu)點(diǎn)能夠極大的提高程序并發(fā)業(yè)務(wù)邏輯的能力缺點(diǎn)異步函數(shù)的書寫方式和代碼執(zhí)行邏輯很不直觀,回調(diào)函數(shù)這種方式不太符合人類的的線性思維異步函數(shù)的執(zhí)行流程 前言 業(yè)務(wù)開發(fā)中經(jīng)常會(huì)用到異步函數(shù),這里簡單的對(duì)異步函數(shù)以及它的各種各樣的解決方案做一個(gè)淺析 優(yōu)缺點(diǎn): 優(yōu)點(diǎn): 能夠極大的提高程序并發(fā)業(yè)務(wù)邏輯的能...

    godiscoder 評(píng)論0 收藏0
  • 切圖崽的自我修養(yǎng)-[ES6] 迭代器Iterator淺析

    摘要:任何數(shù)據(jù)結(jié)構(gòu)只要部署接口,就可以完成遍歷操作即依次處理該數(shù)據(jù)結(jié)構(gòu)的成員。的遍歷某個(gè)數(shù)據(jù)結(jié)構(gòu)過程是這樣的比如對(duì)進(jìn)行遍歷創(chuàng)建一個(gè)指針對(duì)象,指向當(dāng)前數(shù)組的起始位置。 Iterator 這真是毅種循環(huán) Iterator不是array,也不是set,不是map, 它不是一個(gè)實(shí)體,而是一種訪問機(jī)制,是一個(gè)用來訪問某個(gè)對(duì)象的接口規(guī)范,為各種不同的數(shù)據(jù)結(jié)構(gòu)提供統(tǒng)一的訪問機(jī)制。任何數(shù)據(jù)結(jié)構(gòu)只要部署Ite...

    neu 評(píng)論0 收藏0
  • 切圖崽的自我修養(yǎng)-[ES6] 迭代器Iterator淺析

    摘要:任何數(shù)據(jù)結(jié)構(gòu)只要部署接口,就可以完成遍歷操作即依次處理該數(shù)據(jù)結(jié)構(gòu)的成員。的遍歷某個(gè)數(shù)據(jù)結(jié)構(gòu)過程是這樣的比如對(duì)進(jìn)行遍歷創(chuàng)建一個(gè)指針對(duì)象,指向當(dāng)前數(shù)組的起始位置。 Iterator 這真是毅種循環(huán) Iterator不是array,也不是set,不是map, 它不是一個(gè)實(shí)體,而是一種訪問機(jī)制,是一個(gè)用來訪問某個(gè)對(duì)象的接口規(guī)范,為各種不同的數(shù)據(jù)結(jié)構(gòu)提供統(tǒng)一的訪問機(jī)制。任何數(shù)據(jù)結(jié)構(gòu)只要部署Ite...

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

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

0條評(píng)論

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