JS循环中正确使用async、await的姿势分享
作者:毕了业就退休 发布时间:2024-05-25 15:18:56
概览(循环方式 - 常用)
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 进行处理。
结语:由于工作中遇到了超大表单抽离组件,异步校验是遇到了此问题,后来经过查阅资料总结出来的结果
来源:https://juejin.cn/post/7041858551538515981


猜你喜欢
- 在windows操作系统上使用IE作为浏览器时。常常会发生这样的问题:在浏览使用UTF-8编码的网页时,浏览器无法自动侦测(即没有设定“自动
- pyecharts显示数据为百分比的柱状图pyecharts是做数据分析的好帮手,柱状图比较简单,网站例子不够多,一般柱状图就是直接传两组数
- 很多网站都有此功能,当浏览到底部时都会有一个打印按钮,点击打印按钮就可以完成打印功能,功能非常不错,人性化,代码非常的简单。<a hr
- 安装(fastcgi模式)的时候,常常有这样一句命令:/usr/local/webserver/php/bin/phpize一、phpize
- 本文实例讲述了Python文件去除注释的方法。分享给大家供大家参考。具体实现方法如下:#!/usr/bin/python # -*- cod
- 问题:MySQL 8.0 无法远程连接访问原因:可能是mysql数据库user表中,用户的 host 字段配置是不允许当前hos
- 在平时开发过程中,经常遇到需要在数据中获取特定的元素的信息,如到达目的地最近的车站,橱窗里面最贵的物品等等。怎么办?看下面方法一: 利用数组
- 1.获取所有数据库名: SELECT Name FROM Master..SysDatabases ORDER BY Name2.获取所有表
- 目录实验环境依赖项安装编程实现浏览器有一个可以用于展示网页的窗口代码总结实验环境操作系统:Linux Mint编辑器:vim编程语言:pyt
- 1.paramiko概述ssh是一个协议,OpenSSH是其中一个开源实现,paramiko是Python的一个库,实现了SSHv2协议(底
- Python使用QRCode模块生成二维码QRCode官网https://pypi.python.org/pypi/qrcode/5.1简介
- 1) 使用字典dict()循环遍历出一个可迭代对象中的元素,如果字典没有该元素,那么就让该元素作为字典的键,并将该键赋值为1,如果存在就将该
- 和其他语言不一样,传递参数的时候,python不允许程序员选择采用传值还是传引用。Python参数传递采用的肯定是“传对象引用”的方式。实际
- 目录1、条件语句1.1 if语句2、嵌套的分支语句3、案例练习4、循环语句4.1 for-in循环4.2 range()函数4.3 实例1:
- 这篇文章主要介绍了Python tkinter常用操作代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,
- 前言采集教务系统成绩单是一个非常有意义的项目。在现代教育中,教务系统已经成为了学校管理和教学工作的重要组成部分。然而,由于各种原因,教务系统
- SQL*DBA命令的安全性: 如果您没有SQL*PLUS应用程序,您也可以使用SQL*DBA作SQL查权限相关的命令只能分配给Oracle软
- react-native安装流程1.npx react-native init AwesomeProject报错运行 cd ./demo/i
- 当孔乙己说回字有四样写法的时候,相信各位都是这样的表情吧?但是,如果孔乙己说NumPy数组有四种乘法的时候,各位大约就是这样的表情了吧?实际
- 按需导入:安装插件首先需要引入额外的插件:前**vite-plugin-components已重命名为unplugin-vue-compon