JS循環中正確使用async、await的姿勢分享
概覽(循環方式 – 常用)
- for
- map
- forEach
- filter
聲明遍歷的數組和異步方法
聲明一個數組:⬇️
const skills = ['js', 'vue', 'node', 'react']
再聲明一個promise的異步代碼: ⬇️
function getSkillPromise (value) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(value) }, 1000) }) }
for 循環中使用
由於for循環並非函數,而async、await需要在函數中使用,因此需要在for循環外套一層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() // 調用
當使用await時,希望JavaScript暫停執行,直到等待 promise 返回處理結果。上述結果意味著for循環中有異步代碼,是可以等到for循環中異步代碼完全跑完之後再執行for循環後面的代碼。
但是他不能處理回調的循環,如forEach、map、filter等,下面具體分析。
map 中使用
在map中使用await, map 的返回值始是promise數組,這是因為異步函數總是返回promise。
async function test () { console.log('start') const res = skills.map(async item => { return await getSkillPromise(item) }) console.log(res) console.log('end') } test()
結果:始終為promise數組
start [ Promise { <pending> }, Promise { <pending> }, Promise { <pending> }, Promise { <pending> } ] end
若果你想要等到promise的返回結果,可以使用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() // 結果 start [ 'js', 'vue', 'node', 'react' ] end
forEach 中使用
先上代碼和結果
async function test () { console.log('start') skills.forEach(async item => { const res = await getSkillPromise(item) console.log(res) }) console.log('end') } test()
預期結果
‘Start’
‘js’
‘vue’
‘node’
‘react’
‘End’
實際結果 在forEach循環等待異步結果返回之前就執行瞭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() // 調用 // 結果 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()
預期結果:
start
[ ‘vue’, ‘react’ ]
end
實際結果:
[ ‘js’, ‘vue’, ‘node’, ‘react’ ]
end
結論:因為異步函數getSkillPromise返回結果返回的promise總是真的,所以所有選項都通過瞭過濾
附使用小結
- 如果你想連續執行await調用,請使用for循環(或任何沒有回調的循環)。
- 永遠不要和forEach一起使用await,而是使用for循環(或任何沒有回調的循環)。
- 不要在 filter 和 reduce 中使用 await,如果需要,先用 map 進一步驟處理,然後在使用 filter 和 reduce 進行處理。
結語:由於工作中遇到瞭超大表單抽離組件,異步校驗是遇到瞭此問題,後來經過查閱資料總結出來的結果
總結
到此這篇關於JS循環中正確使用async、await的文章就介紹到這瞭,更多相關JS循環中使用async、await內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- es7中的async、await使用方法示例詳解
- JavaScript中的異步能省掉await嗎?
- JavaScript詳解使用Promise處理回調地獄與async await修飾符
- JS中的async與await怎麼使用
- 一文秒懂nodejs中的異步編程