【面试题】在JS循环中使用await会怎么样?
前言
这个问题是这样产生的?某天,在学习异步的知识遇到这样一道题:使用Promise的方式,每隔一秒输出数组中一个值
const arr = [1, 2, 3]
arr.reduce((pre, cur) => {return pre.then(() => {returnnewPromise((resolve, reject) => {setTimeout(() => {resolve(console.log(cur))}, 1000);})})
}, Promise.resolve())
复制代码那这段代码还是挺好了解的,相当于
Promise.resolve().then(() => {returnnewPromise((resolve, reject) => {setTimeout(() => {resolve(console.log(1))}, 1000);})
}).then(() => {returnnewPromise((resolve, reject) => {setTimeout(() => {resolve(console.log(2))}, 1000);})
}).then(() => {returnnewPromise((resolve, reject) => {setTimeout(() => {resolve(console.log(3))}, 1000);})
})
复制代码看完之后,我就在想,如果我在循环中,每次输出值之后停止一秒,也可以解决,于是乎就有了以下代码
const arr = [1, 2, 3]
constsleep = (ms) => {returnnewPromise((resolve, reject) => {setTimeout(() => {resolve()}, ms)})
}
for (let i = 0; i < arr.length; i++) {console.log(arr[i]);awaitsleep(1000)
}
复制代码打印结果也是符合预期的,在这里我就产生了第一个疑问:await不是要搭配async使用的么?这里怎么能单独使用?(不信你把代码放到浏览器控制台试试)
接着我把for改成了forEach,发现根本达不到效果,第二个疑问产生:forEach中await为什么失效了呢?
arr.forEach(async item => {console.log(item);await sleep(1000)
})
复制代码带着这两个疑问,那就开始学习起来,寻找答案。
在for循环中的await
记得在学习async/await的时候有这样一句话,await只能和async搭配一起使用,其实这句话是没有错的。那为什么前面可以直接写await呢,因为我是直接写在浏览器控制台的,咱们在编辑器写代码的时候一定要套一个async使用的
<script> const arr = [1, 2, 3]constsleep = (ms) => {returnnewPromise((resolve, reject) => {setTimeout(() => {resolve()}, ms)})}constlogByOneSecond = async () => {for (let i = 0; i < arr.length; i++) {console.log(arr[i]);awaitsleep(1000)}} logByOneSecond()</script>
复制代码所以这就算闹了个笑话,哈哈,不过当我遇到不理解的时候,又多了一个思考方向。
好的,如上所述,await确实发挥了他的作用,让JS直到等到了promise返回的处理结果,再继续往下执行;那for...of,while是不是也可以呢
const logByForof = async () => {for (const item of arr) {console.log(item);await sleep(1000)}
}
logByForof()
复制代码constlogByWhile = async () => {let i = 0while (i !== arr.length) {awaitsleep(1000)console.log(arr[i]);i++}
}
logByWhile()
复制代码结果也是符合预期,可以在循环中使用await并实现效果
在forEach循环中的await
如一开始,在forEach中并没有的到预期的效果;首先得到一个结果:forEach中async 和await是无效的。
那我看到的解释有以下几种
JavaScript 中的 forEach不支持 promise 感知,也不支持 async 和await,所以不能在 forEach 使用 await 。
map/forEach内部使用了while结合callback方式来执行函数,await不会等待callback的执行
forEach 只支持同步代码
第二种说法,简化以后的伪代码,如下
while(index < arr.length){callback(item, index)
}
复制代码map/forEach是简单的执行下回调函数,并不会处理异步的情况。即:map/forEach 会同时创建出多个回调函数,多个回调函数被加上了各自的 async、await,如下
async ()=>{await sleep(1000);
}
async ()=>{ await sleep(1000);
}
async ()=>{ await sleep(1000);
}
复制代码各个函数之间是独立的,彼此的回调也是独立的;请求是异步的,彼此之间又没有关联,顺序也就自然无法保证
总结
回顾了 async/await 在循环语句里的使用方法,对于普通的 for-loop,所有的 await 都是串行调用的,可以放心使用,包括 while、for-in、for-of 等等;但是在有 callback 的 array 方法,如 forEach、map、filter、reduce 等等,有许多副作用,最好就别使用 await 了。
大厂面试题分享 面试题库
前端后端面试题库 (面试必备) 推荐:★★★★★
地址:前端面试题库
相关文章:
【面试题】在JS循环中使用await会怎么样?
前言这个问题是这样产生的?某天,在学习异步的知识遇到这样一道题:使用Promise的方式,每隔一秒输出数组中一个值const arr [1, 2, 3] arr.reduce((pre, cur) > {return pre.then(() > {returnnewPromise((resolve, rejec…...
Qt QMessageBox详解
文章目录一.QMessageBox介绍枚举属性函数二.QMessageBox的用法1.导入QMessage库2.弹窗提示3.提供选项的弹窗提示4.作为提示,报警,报错提示窗口一.QMessageBox介绍 文本消息显示框(message box)向用户发出情况警报信息并进一步解释警报或向用户提问&…...
Flutter之beamer路由入门指南
beamer路由入门指南 前言使用方法1、路由配置方式1路由配置方式2路由跳转测试现象前言 Beamer是一个很好用的路由组件,本文以beamer1.5.0版本进行说明,前面博主也介绍了其他路由组件 Flutter实战之go_router路由组件入门指南 、 Flutter之Fluro路由组件入门指南 Flutter之Ge…...
「基础篇」机器学习概览
文章目录1. 什么是机器学习2. 引入机器学习3. 应用场景4. 机器学习分类4.1. 有无人类监督4.2. 是否增量学习4.3. 泛化方式5. 主要挑战6. 测试与验证1. 什么是机器学习 机器学习(Machine Learning,ML)是一个研究领域,让计算机无需…...
揭秘可视化图探索工具 NebulaGraph Explore 是如何实现图计算的
前言 在可视化图探索工具 NebulaGraph Explorer 3.1.0 版本中加入了图计算工作流功能,针对 NebulaGraph 提供了图计算的能力,同时可以利用工作流的 nGQL 运行能力支持简单的数据读取,过滤及写入等数据处理功能。 本文将简单分享下 NebulaGr…...
移动架构43_什么是Jetpack
Android移动架构汇总 文章目录一 Android 开发框架演变1 MVC2 MVP3 MVVM二 什么是JetPack三 如何构建支持Jetpack项目一 Android 开发框架演变 1 MVC Model-View-Controller,模型-视图-控制器,Model负责数据管理,View负责UI显…...
TiDB的分布式事务原理探究
事务开启 获取全局授时作为startTS构建一个tikvTxn对象(包括snapshot)。 事务写 txn.Set方法本质上将kv值写入了一个内存缓存(即kv/memdb_buffer.go中的memDbBuffer)中。该内存kv数据库利用的是golevel提供的功能。 事务回滚 直接将tikvTxn的valid字段…...
【C语言】函数指针和指针函数
文章目录[TOC](文章目录)前言概述函数指针定义:使用:回调函数指针函数前言 今天学一下函数指针 提示:以下是本篇文章正文内容,下面案例可供参考 概述 函数指针:是一个指向函数的指针,在内存空间中存放的…...
Nodejs中npx简介和作用
一、npx简介npm从5.25.2版开始,增加了 npx 命令。方便了我在项目中使用全局包。二、安装Node安装后自带npm模块,可以直接使用npx命令。如果不能使用用,就要手动安装一下。npm install -g npx三、使用npx想要解决的主要问题,就是调…...
Matplotlib精品学习笔记001——绘制3D图形详解+实例讲解
3D图片更生动,或许在时间序列数据的展示上更胜一筹 想法: 学习3D绘图的想法来自科研绘图中。我从事的专业是古植物学,也就是和植物化石打交道。化石有三大信息:1.物种信息,也就是它的分类学价值;2.时间信息…...
学习ifconfig实战技巧,成为网络管理高手
文章目录前言一. ifconfig 命令介绍二. 语法格式及常用选项三. 参考案例3.1 显示网络设备信息3.2 启动和关闭指定的网卡3.3 对指定的网卡设备执行修改IP地址操作3.4 启动和关闭ARP协议3.5 使用ifconfig添加网卡总结前言 大家好,又见面了,我是沐风晓月&a…...
day38|70. 爬楼梯(进阶)、322. 零钱兑换、279.完全平方数
70. 爬楼梯(进阶) 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例 1: 输入:n 2 输出:2 解释:有两种方法可以爬到楼顶。 1. 1 阶 1 阶 2. 2…...
SpringBoot全局异常处理
一、目的 当客户端/前端向服务端发送一个请求后,这个请求并不是每次都能完全正确的处理,比如出现一些资源不存在、参数错误或者内部错误等信息的时候,就需要将异常反馈给客户端或者前端。那么这就需要程序有完整的异常处理机制。 在 Java 中所…...
SpringBoot异常处理
目录 一、 错误处理 1. 默认规则 2. 定制错误处理逻辑 二、自定义异常处理 1. 实现 ErrorController 2. RestControllerAdvice/ControllerAdvice ExceptionHandler 实现自定义异常 3. 新建 UserController.class 测试 3 种不同异常的处理 4. 最终效果如下 补充 1. 参…...
《C++ Primer Plus》(第6版)第8章编程练习
《C Primer Plus》(第6版)第8章编程练习《C Primer Plus》(第6版)第8章编程练习1. 打印字符串2. CandyBar3. 将string对象的内容转换为大写4. 设置并打印字符串5. max5()6. maxn()7. SumArray()《C Primer Plus》(第6版…...
RAD Studio 11.3 Alexandria Crack
RAD Studio 11.3 Alexandria Crack 瞄准最新平台版本-此版本增加了对Android 13和Apple macOS Ventura的官方支持。它还支持Ubuntu 22 LTS和Microsoft Windows Server 2022。 使用生物特征认证-New为FireMonkey移动应用程序提供了新的移动生物特征认证组件。 部署嵌入式InterBa…...
Stm32 iic 协议使用
/* 第1个参数为I2C操作句柄 第2个参数为从机设备地址 第3个参数为从机寄存器地址 第4个参数为从机寄存器地址长度 第5个参数为发送的数据的起始地址 第6个参数为传输数据的大小 第7个参数为操作超时时间 */ HAL_I2C_Mem_Write(&hi2c2,salve_add,0,0,PA_BUFF,sizeof(PA_BUFF…...
Malware Dev 02 - Windows SDDL 后门利用之 SCManager
写在最前 如果你是信息安全爱好者,如果你想考一些证书来提升自己的能力,那么欢迎大家来我的 Discord 频道 Northern Bay。邀请链接在这里: https://discord.gg/9XvvuFq9Wb我拥有 OSCP,OSEP,OSWE,OSED&…...
每日一题29——山峰数组的顶部
符合下列属性的数组 arr 称为 山峰数组(山脉数组) : arr.length > 3 存在 i(0 < i < arr.length - 1)使得: arr[0] < arr[1] < ... arr[i-1] < arr[i] arr[i] > arr[i1] > ... &g…...
Linux- 系统随你玩之--好用到炸裂的系统级监控、诊断工具
文章目录1、前言2、lsof介绍2.1、问题来了: 所有用户都可以采用该命令吗?3、 服务器安装lsof3.1、安装3.2、检查安装是否正常。4、lsof 命令4.1、常用功能选项4.2、输出内容4.2.1 、FD和 TYPE列5、 lsof 命令实操常见用法6 、常用组合命令7、 结语1、前言…...
开源工具Jellyfin豆瓣插件高效配置指南:打造完美中文媒体库
开源工具Jellyfin豆瓣插件高效配置指南:打造完美中文媒体库 【免费下载链接】jellyfin-plugin-douban Douban metadata provider for Jellyfin 项目地址: https://gitcode.com/gh_mirrors/je/jellyfin-plugin-douban 在数字媒体收藏日益增长的今天࿰…...
对抗训练新玩法:用AdverIN攻击自己反而提升医学分割模型20%泛化性
医学影像分割的对抗训练革命:AdverIN如何让模型在新设备上表现更优 医学影像分析领域正面临一个尴尬的现实:实验室里表现优异的深度学习模型,在真实临床环境中常常"水土不服"。不同医院使用的扫描设备、成像协议差异导致的域偏移&a…...
别再只会调库了!用NumPy和Random手搓一个SMOTE算法,我踩过的坑都在这了
从零实现SMOTE算法:NumPy实战与关键问题解析 理解类别不平衡问题的本质 在数据科学和机器学习领域,我们经常会遇到类别分布严重不均衡的数据集。想象一下,你正在处理一个信用卡欺诈检测项目,正常交易记录可能有数百万条࿰…...
新手入门:用快马平台生成第一个labelimg式图像标注demo
今天想和大家分享一个特别适合计算机视觉新手的小项目——用InsCode(快马)平台快速搭建一个简易版的图像标注工具。这个工具类似labelimg的核心功能,但更轻量级,能帮助理解数据标注的基本流程。 项目背景理解 图像标注是计算机视觉的基础环节,…...
机械臂robotic-arm--8.snapshot.7
机械臂作为自动化领域的核心设备,其设计精度与功能稳定性直接影响任务执行效率。以robotic-arm--8.snapshot.7为例,其核心作用体现在多维度空间定位与复杂轨迹规划能力上。通过集成高精度伺服电机与闭环控制系统,该型号机械臂可实现亚毫米级重…...
vs code 实现source insight中的快捷键功能
1.自定义快捷键连续两组快捷键CtrlK CtrlS打开键盘快捷键定义界面修改向前向后的快捷键。ctrlu删除当前行复制当前行到下面2.增加bookmarks功能扩展部分装插件,定义快捷键ctrlm增加标签可以修改标签3.多行移动多行向上移动,向下移动Windows/Linux 用 Alt…...
Venera:5大革新功能打造无缝全平台漫画阅读体验
Venera:5大革新功能打造无缝全平台漫画阅读体验 【免费下载链接】venera A comic app 项目地址: https://gitcode.com/gh_mirrors/ve/venera Venera 是一款开源跨平台漫画应用,专为漫画爱好者打造全设备同步的阅读解决方案。无论你使用 Windows、…...
3D打印机步进电机参数计算全攻略:从同步带到丝杆的实战配置
3D打印机步进电机参数计算全攻略:从同步带到丝杆的实战配置 在DIY 3D打印机的过程中,步进电机的参数计算往往是让初学者最头疼的环节之一。无论是同步带驱动的XY轴,还是丝杆控制的Z轴,亦或是齿轮传动的挤出机构,都需要…...
高效PDF处理:用PDF Arranger实现极简文档管理
高效PDF处理:用PDF Arranger实现极简文档管理 【免费下载链接】pdfarranger Small python-gtk application, which helps the user to merge or split PDF documents and rotate, crop and rearrange their pages using an interactive and intuitive graphical int…...
VS2022项目复制后报错打不开?别慌,手把手教你用记事本5分钟修复.sln文件
VS2022项目复制后报错打不开?记事本5分钟修复.sln文件全指南 刚复制完的VS2022项目一打开就报错?解决方案资源管理器一片空白?别急着重装或放弃,这很可能只是.sln文件中的路径需要手动更新。作为经历过数十次类似问题的开发者&…...
