JS中的async與await異步編程及await使用陷阱
ECMA2017中新加入了兩個(gè)關(guān)鍵字async與await
簡單來說它們是基于promise之上的的語法糖,可以讓異步操作更加地簡單明了
首先我們需要用async關(guān)鍵字,將函數(shù)標(biāo)記為異步函數(shù)
async function f() {
}
f()異步函數(shù)就是指:返回值為promise對象的函數(shù)
比如之前用到的fetch()就是一個(gè)異步函數(shù),返回的是promise
在異步函數(shù)中,我們可以調(diào)用其他的異步函數(shù),不過我們不再需要使用then,而是使用一個(gè)await。
await會(huì)等待Promise完成之后直接返回最終結(jié)果
所以這里的response已經(jīng)是一個(gè)服務(wù)器返回的響應(yīng)數(shù)據(jù)了
async function f() {
const response = await fetch("http://....")
}
f()雖然await看上去會(huì)暫停函數(shù)的執(zhí)行,但在等待的過程中,js同樣可以處理其他的任務(wù)
這是因?yàn)閍wait底層是基于promise與事件循環(huán)(event loop)機(jī)制實(shí)現(xiàn)的
await使用時(shí)的陷阱:
1、第一個(gè)陷阱
比如:我們分別去await這兩個(gè)異步操作
async function f() {
const a = fetch("http://..../post/1")
const b = fetch("http://..../post/2")
}
f()雖然不存在邏輯錯(cuò)誤
但這樣會(huì)打破這兩個(gè)fetch()操作的并行
因?yàn)槲覀儠?huì)等到第一個(gè)任務(wù)執(zhí)行完成之后才開始執(zhí)行第二個(gè)任務(wù)
這里更高效的方法是將所有的Promise用Promise.all組合起來,然后再去await:
修改之后的執(zhí)行效率會(huì)直接提升一倍
async function f() {
const promiseA = fetch("http://..../post/1")
const promiseB = fetch("http://..../post/2")
const [a, b] = await Promise.all([promiseA,promiseB])
}
f()2、第二個(gè)陷阱
如果我們需要在循環(huán)中執(zhí)行異步操作,是不能夠直接調(diào)用forEach或者map這一類方法的,盡管我們在回調(diào)函數(shù)中寫了await也不行。
因?yàn)檫@里的forEach會(huì)立即返回,它并不會(huì)等到所有的異步操作都執(zhí)行完畢
async function f() {
[1,2,3].forEach(async (i) => {
await someAsyncOperation();
})
console.log("done")
}
f()如果我們希望等待循環(huán)中的異步操作都一一完成之后才繼續(xù)執(zhí)行
我們應(yīng)當(dāng)使用傳統(tǒng)的for循環(huán)
async function f() {
for( let i of [1,2,3]){
await someAsyncOperation();
}
console.log("done")
}
f()如果我們希望所有的程序并發(fā)執(zhí)行,一種更炫酷的寫法就是使用for await
這里的for循環(huán)依然會(huì)等到所有的異步操作都完成之后才會(huì)繼續(xù)向后執(zhí)行

3、第三個(gè)陷阱
我們不能在全局或者普通函數(shù)中直接使用await關(guān)鍵字
await只能用在異步函數(shù)(async function)中
如果我們想要在最外層中使用await,那么需要先定義一個(gè)異步函數(shù):

使用await async可以讓我們寫出更清晰,更容易理解的異步代碼
到此這篇關(guān)于async與await異步編程的文章就介紹到這了,更多相關(guān)async與await異步編程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS實(shí)現(xiàn)跟隨鼠標(biāo)立體翻轉(zhuǎn)圖片的方法
這篇文章主要介紹了JS實(shí)現(xiàn)跟隨鼠標(biāo)立體翻轉(zhuǎn)圖片的方法,涉及javascript操作圖片翻轉(zhuǎn)的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-05-05
JS運(yùn)動(dòng)框架之分享側(cè)邊欄動(dòng)畫實(shí)例
這篇文章主要介紹了JS運(yùn)動(dòng)框架之分享側(cè)邊欄動(dòng)畫,實(shí)例分析了javascript操作div及css的技巧,需要的朋友可以參考下2015-03-03
JavaScript實(shí)現(xiàn)獲取select下拉框中第一個(gè)值的方法
這篇文章主要介紹了JavaScript實(shí)現(xiàn)獲取select下拉框中第一個(gè)值的方法,涉及javascript針對頁面元素屬性的相關(guān)獲取操作技巧,需要的朋友可以參考下2018-02-02
JS面向?qū)ο缶幊袒A(chǔ)篇(二) 封裝操作實(shí)例詳解
這篇文章主要介紹了JS面向?qū)ο缶幊谭庋b操作,結(jié)合實(shí)例形式詳細(xì)分析了JS面向?qū)ο蠓庋b操作的相關(guān)概念、原理、使用方法與操作注意事項(xiàng),需要的朋友可以參考下2020-03-03
Bootstrap Paginator+PageHelper實(shí)現(xiàn)分頁效果
這篇文章主要為大家詳細(xì)介紹了Bootstrap Paginator+PageHelper實(shí)現(xiàn)分頁效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12
釘釘小程序web-view內(nèi)嵌H5頁面并實(shí)現(xiàn)通信
本文主要介紹了釘釘小程序web-view內(nèi)嵌H5頁面并實(shí)現(xiàn)通信,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05

