JS循環(huán)中正確使用async、await的姿勢分享
概覽(循環(huán)方式 - 常用)
- for
- map
- forEach
- filter
聲明遍歷的數(shù)組和異步方法
聲明一個數(shù)組:??
const skills = ['js', 'vue', 'node', 'react']
再聲明一個promise的異步代碼: ??
function getSkillPromise (value) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(value) }, 1000) }) }
for 循環(huán)中使用
由于for循環(huán)并非函數(shù),而async、await需要在函數(shù)中使用,因此需要在for循環(huán)外套一層function
async function test () { for (let i = 0; i < skills.length; i++) { const skill = skills[i] const res = await getSkillPromise(skill) console.log(res) } } test() // 調(diào)用
當(dāng)使用await時,希望JavaScript暫停執(zhí)行,直到等待 promise 返回處理結(jié)果。上述結(jié)果意味著for循環(huán)中有異步代碼,是可以等到for循環(huán)中異步代碼完全跑完之后再執(zhí)行for循環(huán)后面的代碼。
但是他不能處理回調(diào)的循環(huán),如forEach、map、filter等,下面具體分析。
map 中使用
在map中使用await, map 的返回值始是promise數(shù)組,這是因為異步函數(shù)總是返回promise。
async function test () { console.log('start') const res = skills.map(async item => { return await getSkillPromise(item) }) console.log(res) console.log('end') } test()
結(jié)果:始終為promise數(shù)組
start [ Promise { <pending> }, Promise { <pending> }, Promise { <pending> }, Promise { <pending> } ] end
若果你想要等到promise的返回結(jié)果,可以使用promise.all()處理一下
async function test () { console.log('start') const res = skills.map(async item => { return await getSkillPromise(item) }) const resPromise = await Promise.all(res) console.log(resPromise) console.log('end') } test() // 結(jié)果 start [ 'js', 'vue', 'node', 'react' ] end
forEach 中使用
先上代碼和結(jié)果
async function test () { console.log('start') skills.forEach(async item => { const res = await getSkillPromise(item) console.log(res) }) console.log('end') } test()
預(yù)期結(jié)果
'Start'
'js'
'vue'
'node'
'react'
'End'
實際結(jié)果 在forEach循環(huán)等待異步結(jié)果返回之前就執(zhí)行了console.log('end')
'Start'
'End'
'js'
'vue'
'node'
'react'
JavaScript 中的 forEach不支持 promise 感知,也支持 async 和await,所以不能在 forEach 使用 await 。
filter 中使用
使用filter過濾item為vue或者react的選項
正常使用 filter:
async function test () { console.log('start') const res = skills.filter(item => { return ['vue', 'react'].includes(item) }) console.log(res) console.log('end') } test() // 調(diào)用 // 結(jié)果 start [ 'vue', 'react' ] end
使用 await后:
async function test () { console.log('start') const res = skills.filter(async item => { const skill = await getSkillPromise(item) return ['vue', 'react'].includes(item) }) console.log(res) console.log('end') } test()
預(yù)期結(jié)果:
start
[ 'vue', 'react' ]
end
實際結(jié)果:
[ 'js', 'vue', 'node', 'react' ]
end
結(jié)論:因為異步函數(shù)getSkillPromise返回結(jié)果返回的promise總是真的,所以所有選項都通過了過濾
附使用小結(jié)
- 如果你想連續(xù)執(zhí)行await調(diào)用,請使用for循環(huán)(或任何沒有回調(diào)的循環(huán))。
- 永遠(yuǎn)不要和forEach一起使用await,而是使用for循環(huán)(或任何沒有回調(diào)的循環(huán))。
- 不要在 filter 和 reduce 中使用 await,如果需要,先用 map 進(jìn)一步驟處理,然后在使用 filter 和 reduce 進(jìn)行處理。
結(jié)語:由于工作中遇到了超大表單抽離組件,異步校驗是遇到了此問題,后來經(jīng)過查閱資料總結(jié)出來的結(jié)果
總結(jié)
到此這篇關(guān)于JS循環(huán)中正確使用async、await的文章就介紹到這了,更多相關(guān)JS循環(huán)中使用async、await內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript控制網(wǎng)頁層收起和展開效果的方法
這篇文章主要介紹了JavaScript控制網(wǎng)頁層收起和展開效果的方法,涉及javascript操作網(wǎng)頁元素動態(tài)效果的技巧,非常具有實用價值,需要的朋友可以參考下2015-04-04Javascript中查找不以XX字符結(jié)尾的單詞示例代碼
我在寫這篇文章之前花了2個多小時在弄正則表達(dá)式,下為大家介紹下具體的實現(xiàn)思路,感興趣的朋友可以參考下2013-10-10