当前位置: 首页 > news >正文

【面试题】在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是无效的。

那我看到的解释有以下几种

  1. JavaScript 中的 forEach不支持 promise 感知,也不支持 async 和await,所以不能在 forEach 使用 await 。

  1. map/forEach内部使用了while结合callback方式来执行函数,await不会等待callback的执行

  1. 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会怎么样?

前言这个问题是这样产生的&#xff1f;某天&#xff0c;在学习异步的知识遇到这样一道题&#xff1a;使用Promise的方式&#xff0c;每隔一秒输出数组中一个值const arr [1, 2, 3] ​ arr.reduce((pre, cur) > {return pre.then(() > {returnnewPromise((resolve, rejec…...

Qt QMessageBox详解

文章目录一.QMessageBox介绍枚举属性函数二.QMessageBox的用法1.导入QMessage库2.弹窗提示3.提供选项的弹窗提示4.作为提示&#xff0c;报警&#xff0c;报错提示窗口一.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. 什么是机器学习 机器学习&#xff08;Machine Learning&#xff0c;ML&#xff09;是一个研究领域&#xff0c;让计算机无需…...

揭秘可视化图探索工具 NebulaGraph Explore 是如何实现图计算的

前言 在可视化图探索工具 NebulaGraph Explorer 3.1.0 版本中加入了图计算工作流功能&#xff0c;针对 NebulaGraph 提供了图计算的能力&#xff0c;同时可以利用工作流的 nGQL 运行能力支持简单的数据读取&#xff0c;过滤及写入等数据处理功能。 本文将简单分享下 NebulaGr…...

移动架构43_什么是Jetpack

Android移动架构汇总​​​​​​​ 文章目录一 Android 开发框架演变1 MVC2 MVP3 MVVM二 什么是JetPack三 如何构建支持Jetpack项目一 Android 开发框架演变 1 MVC Model-View-Controller&#xff0c;模型-视图-控制器&#xff0c;Model负责数据管理&#xff0c;View负责UI显…...

TiDB的分布式事务原理探究

事务开启 获取全局授时作为startTS构建一个tikvTxn对象&#xff08;包括snapshot&#xff09;。 事务写 txn.Set方法本质上将kv值写入了一个内存缓存(即kv/memdb_buffer.go中的memDbBuffer)中。该内存kv数据库利用的是golevel提供的功能。 事务回滚 直接将tikvTxn的valid字段…...

【C语言】函数指针和指针函数

文章目录[TOC](文章目录)前言概述函数指针定义&#xff1a;使用&#xff1a;回调函数指针函数前言 今天学一下函数指针 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 概述 函数指针&#xff1a;是一个指向函数的指针&#xff0c;在内存空间中存放的…...

Nodejs中npx简介和作用

一、npx简介npm从5.25.2版开始&#xff0c;增加了 npx 命令。方便了我在项目中使用全局包。二、安装Node安装后自带npm模块&#xff0c;可以直接使用npx命令。如果不能使用用&#xff0c;就要手动安装一下。npm install -g npx三、使用npx想要解决的主要问题&#xff0c;就是调…...

Matplotlib精品学习笔记001——绘制3D图形详解+实例讲解

3D图片更生动&#xff0c;或许在时间序列数据的展示上更胜一筹 想法&#xff1a; 学习3D绘图的想法来自科研绘图中。我从事的专业是古植物学&#xff0c;也就是和植物化石打交道。化石有三大信息&#xff1a;1.物种信息&#xff0c;也就是它的分类学价值&#xff1b;2.时间信息…...

学习ifconfig实战技巧,成为网络管理高手

文章目录前言一. ifconfig 命令介绍二. 语法格式及常用选项三. 参考案例3.1 显示网络设备信息3.2 启动和关闭指定的网卡3.3 对指定的网卡设备执行修改IP地址操作3.4 启动和关闭ARP协议3.5 使用ifconfig添加网卡总结前言 大家好&#xff0c;又见面了&#xff0c;我是沐风晓月&a…...

day38|70. 爬楼梯(进阶)、322. 零钱兑换、279.完全平方数

70. 爬楼梯(进阶) 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方法可以爬到楼顶。 1. 1 阶 1 阶 2. 2…...

SpringBoot全局异常处理

一、目的 当客户端/前端向服务端发送一个请求后&#xff0c;这个请求并不是每次都能完全正确的处理&#xff0c;比如出现一些资源不存在、参数错误或者内部错误等信息的时候&#xff0c;就需要将异常反馈给客户端或者前端。那么这就需要程序有完整的异常处理机制。 在 Java 中所…...

SpringBoot异常处理

目录 一、 错误处理 1. 默认规则 2. 定制错误处理逻辑 二、自定义异常处理 1. 实现 ErrorController 2. RestControllerAdvice/ControllerAdvice ExceptionHandler 实现自定义异常 3. 新建 UserController.class 测试 3 种不同异常的处理 4. 最终效果如下 补充 1. 参…...

《C++ Primer Plus》(第6版)第8章编程练习

《C Primer Plus》&#xff08;第6版&#xff09;第8章编程练习《C Primer Plus》&#xff08;第6版&#xff09;第8章编程练习1. 打印字符串2. CandyBar3. 将string对象的内容转换为大写4. 设置并打印字符串5. max5()6. maxn()7. SumArray()《C Primer Plus》&#xff08;第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

写在最前 如果你是信息安全爱好者&#xff0c;如果你想考一些证书来提升自己的能力&#xff0c;那么欢迎大家来我的 Discord 频道 Northern Bay。邀请链接在这里&#xff1a; https://discord.gg/9XvvuFq9Wb我拥有 OSCP&#xff0c;OSEP&#xff0c;OSWE&#xff0c;OSED&…...

每日一题29——山峰数组的顶部

符合下列属性的数组 arr 称为 山峰数组&#xff08;山脉数组&#xff09; &#xff1a; arr.length > 3 存在 i&#xff08;0 < i < arr.length - 1&#xff09;使得&#xff1a; arr[0] < arr[1] < ... arr[i-1] < arr[i] arr[i] > arr[i1] > ... &g…...

Linux- 系统随你玩之--好用到炸裂的系统级监控、诊断工具

文章目录1、前言2、lsof介绍2.1、问题来了&#xff1a; 所有用户都可以采用该命令吗&#xff1f;3、 服务器安装lsof3.1、安装3.2、检查安装是否正常。4、lsof 命令4.1、常用功能选项4.2、输出内容4.2.1 、FD和 TYPE列5、 lsof 命令实操常见用法6 、常用组合命令7、 结语1、前言…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...