最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

async/await地獄該如何避免詳解

 更新時(shí)間:2018年05月10日 08:36:17   作者:極光推送  
這篇文章主要給大家介紹了關(guān)于async/await地獄該如何避免的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。

前言

async/await是什么

async/await可以說(shuō)是co模塊和生成器函數(shù)的語(yǔ)法糖。用更加清晰的語(yǔ)義解決js異步代碼。

熟悉co模塊的同學(xué)應(yīng)該都知道,co模塊是TJ大神寫的一個(gè)使用生成器函數(shù)來(lái)解決異步流程的模塊,可以看做是生成器函數(shù)的執(zhí)行器。而async/await則是對(duì)co模塊的升級(jí),內(nèi)置生成器函數(shù)的執(zhí)行器,不再依賴co模塊。同時(shí),async返回的是Promise。

從上面來(lái)看,不管是co模塊還是async/await,都是將Promise作為最基礎(chǔ)的單元,對(duì)Promise不很了解的同學(xué)可以先深入了解一下Promise。

async/await 寫著很爽,不過(guò)要注意這些問(wèn)題。

async/await 讓我們擺脫了回調(diào)地獄,但是這又引入了 async/await 地獄的問(wèn)題。

什么是 async/await 地獄

在 Javascript 中進(jìn)行異步編程的時(shí)候,人們總是使用很多 await 語(yǔ)句,很多時(shí)候我們的語(yǔ)句并不需要依賴于之前的語(yǔ)句,這樣就會(huì)導(dǎo)致性能問(wèn)題。

async/await 地獄的例子

我們?cè)囍鴮懸粋€(gè)購(gòu)買披薩和飲料的程序:

(async () => {
 const pizzaData = await getPizzaData() // async call
 const drinkData = await getDrinkData() // async call
 const chosenPizza = choosePizza() // sync call
 const chosenDrink = chooseDrink() // sync call
 await addPizzaToCart(chosenPizza) // async call
 await addDrinkToCart(chosenDrink) // async call
 orderItems() // async call
})()

這段代碼運(yùn)行沒(méi)有問(wèn)題。但是不是一個(gè)好的實(shí)現(xiàn),因?yàn)檫@增加了不必要的等待。

說(shuō)明

我們已經(jīng)將我們的代碼封裝在異步 IIFE 中,按照下面的順序執(zhí)行:

得到披薩名單
獲取飲料列表
從列表中選擇一個(gè)披薩
從列表中選擇一種飲料
將選中的披薩加入購(gòu)物車
將選擇的飲品加入購(gòu)物車
訂購(gòu)購(gòu)物車中的物品

問(wèn)題

這里有個(gè)問(wèn)題為什么從列表中選擇披薩這個(gè)動(dòng)作要等待獲取飲料列表?這兩個(gè)是沒(méi)什么關(guān)聯(lián)的操作。其中的關(guān)聯(lián)操作有兩組:

獲取披薩列表 -》 選擇披薩 -》 選擇披薩加入購(gòu)物車

獲取飲料列表 -》 選擇飲料 -》 選擇飲料加入購(gòu)物車

這兩組操作應(yīng)該是并發(fā)執(zhí)行的。

再來(lái)看一個(gè)更差的例子

這個(gè) Javascript 代碼片段將購(gòu)物車中的商品并發(fā)出訂購(gòu)請(qǐng)求。

async function orderItems() {
 const items = await getCartItems() // async call
 const noOfItems = items.length
 for(var i = 0; i < noOfItems; i++) {
 await sendRequest(items[i]) // async call
 }
}

這種情況 for 循環(huán)必須等待 sendRequest() 函數(shù)完成才能繼續(xù)下一次迭代。但是,我們并不需要等待。我們希望盡快發(fā)送所有請(qǐng)求。然后我們可以等待所有請(qǐng)求完成。

現(xiàn)在你應(yīng)該已經(jīng)對(duì) async/await 地獄有跟多的了解,現(xiàn)在我們?cè)賮?lái)考慮一個(gè)問(wèn)題

如果我們忘記 await 關(guān)鍵字會(huì)怎么樣?

如果在調(diào)用異步函數(shù)忘記使用 await,這意味著執(zhí)行該功能不需要等待。異步函數(shù)將直接返回一個(gè) promise,你可以稍后使用。

(async () => {
 const value = doSomeAsyncTask()
 console.log(value) // an unresolved promise
})()

或者是程序不清楚你想要等待函數(shù)執(zhí)行完,直接退出不會(huì)完成這個(gè)異步任務(wù)。所以我們需要使用 await 這個(gè)關(guān)鍵字。

promise 有一個(gè)有趣的屬性,你可以在某行代碼中獲取 promise,然后在其他地方中等待它 resolve,這是解決 async/await 地獄的關(guān)鍵。

(async () => {
 const promise = doSomeAsyncTask()
 const value = await promise
 console.log(value) // the actual value
})()

如你所見(jiàn) doSomeAsyncTask 直接返回一個(gè) Promise 同時(shí)這個(gè)異步函數(shù) doSomeAsyncTask 已經(jīng)開(kāi)始執(zhí)行,為了得到 doSomeAsyncTask 的返回值,我們需要 await 來(lái)告訴

應(yīng)該如何避免 async/await 地獄

首先我們需要知道哪些命名是有前后依賴關(guān)系的。

然后將有依賴關(guān)系的系列操作進(jìn)行分組合并成一個(gè)異步操作。

同時(shí)執(zhí)行這些異步函數(shù)。

我們來(lái)重寫這寫例子:

async function selectPizza() {
 const pizzaData = await getPizzaData() // async call
 const chosenPizza = choosePizza() // sync call
 await addPizzaToCart(chosenPizza) // async call
}

async function selectDrink() {
 const drinkData = await getDrinkData() // async call
 const chosenDrink = chooseDrink() // sync call
 await addDrinkToCart(chosenDrink) // async call
}

(async () => {
 const pizzaPromise = selectPizza()
 const drinkPromise = selectDrink()
 await pizzaPromise
 await drinkPromise
 orderItems() // async call
})()

// Although I prefer it this way

(async () => {
 Promise.all([selectPizza(), selectDrink()].then(orderItems) // async call
})()

我們將語(yǔ)句分成兩個(gè)函數(shù)。在函數(shù)內(nèi)部,每個(gè)語(yǔ)句都依賴于前一個(gè)語(yǔ)句的執(zhí)行。然后我們同時(shí)執(zhí)行這兩個(gè)函數(shù) selectPizza()和selectDrink() 。

在第二個(gè)例子中我們需要處理未知數(shù)量的 Promise。處理這個(gè)問(wèn)題非常簡(jiǎn)單,我們只需要?jiǎng)?chuàng)建一個(gè)數(shù)組將所有 Promise 存入其中,使用 Promise.all() 方法并行執(zhí)行:

async function orderItems() {
 const items = await getCartItems() // async call
 const noOfItems = items.length
 const promises = []
 for(var i = 0; i < noOfItems; i++) {
 const orderPromise = sendRequest(items[i]) // async call
 promises.push(orderPromise) // sync call
 }
 await Promise.all(promises) // async call
}

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • JS正則匹配中文的方法示例

    JS正則匹配中文的方法示例

    這篇文章主要介紹了JS正則匹配中文的方法,結(jié)合具體實(shí)例形式分析了JS針對(duì)中文的匹配操作相關(guān)技巧與注意事項(xiàng),需要的朋友可以參考下
    2017-01-01
  • JavaScript中的對(duì)象序列化介紹

    JavaScript中的對(duì)象序列化介紹

    這篇文章主要介紹了JavaScript中的對(duì)象序列化介紹,JavaScript中的對(duì)象序列化是通過(guò)JSON.stringify()來(lái)實(shí)現(xiàn)的,而反序列化則通過(guò)JSON.parse()來(lái)實(shí)現(xiàn),需要的朋友可以參考下
    2014-12-12
  • JavaScript中兩種鏈?zhǔn)秸{(diào)用實(shí)現(xiàn)代碼

    JavaScript中兩種鏈?zhǔn)秸{(diào)用實(shí)現(xiàn)代碼

    方法鏈一般適合對(duì)一個(gè)對(duì)象進(jìn)行連續(xù)操作(集中在一句代碼)。一定程度上可以減少代碼量,缺點(diǎn)是它占用了函數(shù)的返回值。
    2011-01-01
  • 不用typsescript如何使用類型增強(qiáng)功能

    不用typsescript如何使用類型增強(qiáng)功能

    這篇文章主要給大家介紹了關(guān)于不用typsescript如何使用類型增強(qiáng)功能的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • BootStrap Table 分頁(yè)后重新搜索問(wèn)題的解決辦法

    BootStrap Table 分頁(yè)后重新搜索問(wèn)題的解決辦法

    這篇文章主要介紹了BootStrap Table 分頁(yè)后重新搜索問(wèn)題的解決辦法,自定義搜索且有分頁(yè)功能,比如搜索產(chǎn)品名的功能。小編給大家?guī)?lái)了關(guān)鍵代碼,非常不錯(cuò),需要的朋友可以參考下
    2016-08-08
  • bootstrap按鈕插件(Button)使用方法解析

    bootstrap按鈕插件(Button)使用方法解析

    這篇文章主要為大家詳細(xì)解析了bootstrap按鈕插件Button使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • javascript函數(shù)的四種調(diào)用模式

    javascript函數(shù)的四種調(diào)用模式

    本文詳細(xì)介紹了javascript函數(shù)的四種調(diào)用模式。具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-01-01
  • JS 判斷某變量是否為某數(shù)組中的一個(gè)值的3種方法(總結(jié))

    JS 判斷某變量是否為某數(shù)組中的一個(gè)值的3種方法(總結(jié))

    下面小編就為大家?guī)?lái)一篇JS 判斷某變量是否為某數(shù)組中的一個(gè)值的3種方法(總結(jié))。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • JavaScript中的動(dòng)態(tài)?import()用法示例解析

    JavaScript中的動(dòng)態(tài)?import()用法示例解析

    這篇文章主要為大家介紹了JavaScript中的動(dòng)態(tài)import()用法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • bootstrap提示標(biāo)簽、提示框?qū)崿F(xiàn)代碼

    bootstrap提示標(biāo)簽、提示框?qū)崿F(xiàn)代碼

    這篇文章主要為大家詳細(xì)介紹了bootstrap提示標(biāo)簽、提示框的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12

最新評(píng)論

简阳市| 琼海市| 成武县| 瑞丽市| 布拖县| 榕江县| 精河县| 阿克| 宿迁市| 靖江市| 辉南县| 东源县| 云阳县| 牙克石市| 南康市| 潞城市| 西乡县| 万州区| 阳高县| 旬阳县| 政和县| 苗栗县| 威信县| 万山特区| 屏南县| 华坪县| 三明市| 专栏| 乌兰浩特市| 安化县| 文化| 东丽区| 湖南省| 鹤山市| 易门县| 麻阳| 沛县| 龙川县| 丰都县| 项城市| 霞浦县|