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总是真的,所以所有选项都通过了过滤作者:毕了业就退休

4 声望
1 粉丝
0 条评论
推荐阅读
ThreadLocal源码分析
在网站实际应用过程中,为了防止网站登录接口被机器人轻易地使用,产生一些没有意义的用户数据,所以,采用验证码进行一定程度上的拦截,当然,我们采用的还是一个数字与字母结合的图片验证码形式,后续会讲到更...

数据先声阅读 42

手把手教你写一份优质的前端技术简历
不知不觉一年一度的秋招又来了,你收获了哪些大厂的面试邀约,又拿了多少offer呢?你身边是不是有挺多人技术比你差,但是却拿到了很多大厂的offer呢?其实,要想面试拿offer,首先要过得了简历那一关。如果一份简...

tonychen152阅读 17.7k评论 5

封面图
正则表达式实例
收集在业务中经常使用的正则表达式实例,方便以后进行查找,减少工作量。常用正则表达式实例1. 校验基本日期格式 {代码...} {代码...} 2. 校验密码强度密码的强度必须是包含大小写字母和数字的组合,不能使用特殊...

寒青56阅读 8.4k评论 11

JavaScript有用的代码片段和trick
平时工作过程中可以用到的实用代码集棉。判断对象否为空 {代码...} 浮点数取整 {代码...} 注意:前三种方法只适用于32个位整数,对于负数的处理上和Math.floor是不同的。 {代码...} 生成6位数字验证码 {代码...} ...

jenemy48阅读 6.9k评论 12

从零搭建 Node.js 企业级 Web 服务器(十五):总结与展望
总结截止到本章 “从零搭建 Node.js 企业级 Web 服务器” 主题共计 16 章内容就更新完毕了,回顾第零章曾写道:搭建一个 Node.js 企业级 Web 服务器并非难事,只是必须做好几个关键事项这几件必须做好的关键事项就...

乌柏木75阅读 7k评论 16

再也不学AJAX了!(二)使用AJAX ① XMLHttpRequest
「再也不学 AJAX 了」是一个以 AJAX 为主题的系列文章,希望读者通过阅读本系列文章,能够对 AJAX 技术有更加深入的认识和理解,从此能够再也不用专门学习 AJAX。本篇文章为该系列的第二篇,最近更新于 2023 年 1...

libinfs42阅读 6.8k评论 12

封面图
从零搭建 Node.js 企业级 Web 服务器(一):接口与分层
分层规范从本章起,正式进入企业级 Web 服务器核心内容。通常,一块完整的业务逻辑是由视图层、控制层、服务层、模型层共同定义与实现的,如下图:从上至下,抽象层次逐渐加深。从下至上,业务细节逐渐清晰。视图...

乌柏木45阅读 8.5k评论 6

4 声望
1 粉丝
宣传栏