【react hook】react hook组件中,在forEach中使用async/awati进行异步操作,为什么后面代码没有等待直接同步运行了呢?
这是因为 forEach 方法不会等待 async/await 异步操作的完成。forEach 方法是一种同步的方法,它会在每个迭代内部同步执行一个回调函数。当遇到 await 时,会立即暂停执行,但是 forEach 方法不会等待回调函数中的 await 异步操作完成,而是立即执行下一个循环。
举个例子,假如在 React Hook 组件中,我们想要通过遍历异步请求一个数组中的数据:
import React, { useState, useEffect } from 'react';function MyComponent() {const [data, setData] = useState([]);useEffect(() => {const fetchData = async () => {const result = [];[1, 2, 3].forEach(async (num) => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${num}`);const data = await response.json();result.push(data);})setData(result);}fetchData();}, []);return (<ul>{data.map(item => <li key={item.id}>{item.title}</li>)}</ul>);
};export default MyComponent;
在这个例子中,使用 forEach 方法来遍历并异步请求数据,然后将请求到的数据添加到 result 数组中。最后,将 result 数组通过 setData 设置为 data 的状态。然而,这个代码并不能达到我们的预期。
原因是 forEach 方法是同步执行的,在执行的过程中会立即调用回调函数。在回调函数中使用 async/await 将请求转为异步操作,当执行到 await 时,虽然会暂停当前的执行,但是 forEach 会继续执行下一次循环,因此 result 数组没有等待所有的异步请求完成后再被更新,而是由于异步请求还没有完成,因此我们只得到了一个空的数组。
解决这个问题的方法是使用 for..of 循环或者 Promise.all。在这里,我提供一个使用 Promise.all 的解决方案:
Promise.all的写法
import React, { useState, useEffect } from 'react';function MyComponent() {const [data, setData] = useState([]);useEffect(() => {const fetchData = async () => {const promises = [1, 2, 3].map(async (num) => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${num}`);return response.json();});const result = await Promise.all(promises);setData(result);}fetchData();}, []);return (<ul>{data.map(item => <li key={item.id}>{item.title}</li>)}</ul>);
};export default MyComponent;
在这个例子中,我们将 forEach 方法替换为 map,用一个数组来保存返回的 Promise。然后,使用 Promise.all 来并行地等待所有的 Promise 被解决,并将它们的值传递给一个数组,然后使用 setData() 方法来更新组件状态。这样就可以达到我们的预期:异步请求完成后更新组件状态。
for…of的写法
使用 for...of 的方法和 forEach 的方法类似,也是使用异步函数进行请求。但是,在 for...of 循环体内部可以使用 await 等待异步操作的完成。例如:
import React, { useState, useEffect } from 'react';function MyComponent() {const [data, setData] = useState([]);useEffect(() => {const fetchData = async () => {const result = [];for (const num of [1, 2, 3]) {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${num}`);const data = await response.json();result.push(data);}setData(result);}fetchData();}, []);return (<ul>{data.map(item => <li key={item.id}>{item.title}</li>)}</ul>);
};export default MyComponent;
在这个例子中,我们使用了 for...of 循环来遍历数组。在循环体内部使用 await 等待异步操作,这样可以保证每个异步操作在上一个异步操作完成后才会被执行。
通过使用 for...of 来遍历数组,可以很好地保证每个异步操作能够按顺序被执行,并且可以等待每个异步操作的完成。这是相对于 forEach 来说的一种更为简洁的方式。
相关文章:
【react hook】react hook组件中,在forEach中使用async/awati进行异步操作,为什么后面代码没有等待直接同步运行了呢?
这是因为 forEach 方法不会等待 async/await 异步操作的完成。forEach 方法是一种同步的方法,它会在每个迭代内部同步执行一个回调函数。当遇到 await 时,会立即暂停执行,但是 forEach 方法不会等待回调函数中的 await 异步操作完成ÿ…...
高斯过程回归 | GPR高斯过程回归
高斯过程回归(Gaussian Process Regression, GPR)是一种强大的非参数回归方法,它通过假设数据是从一个高斯过程中生成的来预测新的数据点。 高斯过程是一种定义在连续输入空间上的随机过程,其中任何有限集合的观测值都呈多变量高斯分布。 实现GPR的Python代码import numpy …...
[autojs]逍遥模拟器和vscode对接
第一步:启动autojs服务 第二步:去cmd查看ip地址,输入ipconfig 第三步:打开逍遥模拟器中的sutojs-左上角- 连接电脑,然后输入WLAN或者其他ip也行,根据自己电脑实际情况确认 此时vscode显示连接成功。我们写…...
Docker 安装与优化
一、安装Docker 1、关闭防火墙 systemctl stop firewalld systemctl disable firewalld setenforce 02、安装依赖包 yum -y install yum-utils device-mapper-persistent-data lvm2#解释 yum-utils #提供了yum-config-manager工具 device mapper #是linux内核中支持逻辑卷…...
Wix使用velo添加Google ads tag并在form表单提交时向谷歌发送事件
往head里加代码时,不能看谷歌的代码,要看wix的代码,不然必定踩坑 https://support.wix.com/en/article/tracking-google-ads-conversions-using-wix-custom-code 这里的代码才对,因为wix搞了个velo,这个velo很傻x&am…...
Centos配置邮件发送
在CentOS Linux上配置邮件发送 在这个指南中,我们将讨论如何配置CentOS Linux系统以通过外部邮件服务器发送电子邮件,使用自己的邮件账户进行发送。 第一步:开启SMTP授权码 首先,我们以QQ邮箱为例,需要开启SMTP授权…...
Ubuntu系统使用apt-get管理软件工具
记录一下使用Ubuntu系统的apt-get管理软件工具 先查看一下系统的版本,可以看到这里使用的是Ubuntu20.04版本,版本代号focal rootmyw:~# uname -a Linux myw 5.4.0-70-generic #78-Ubuntu SMP Fri Mar 19 13:29:52 UTC 2021 x86_64 x86_64 x86_64 GNU/L…...
带你走进Cflow (三)·控制符号类型分析
目录 编辑 1、控制符号类型 1.1 语法类 1.2 符号别名 1.3 GCC 初始化 1、控制符号类型 有人也许注意到了输出中奇怪的现象:函数_exit 丢失了,虽然它在源文件中被printdir 调用了两次。这是因为默认情况下 cflow 忽略所有的一下划线开头的符号…...
FPGA UDP RGMII 千兆以太网(3)ODDR
1 xilinx原语 在 7 系列 FPGA 中实现 RGMII 接口需要借助 5 种原语,分别是:IDDR、ODDR、IDELAYE2、ODELAYE2(A7 中没有)、IDELAYCTRL。其中,IDDR和ODDR分别是输入和输出的双边沿寄存器,位于IOB中。IDELAYE2和ODELAYE2,分别用于控制 IO 口输入和输出延时。同时,IDELAYE2 …...
OSG交互:选中场景模型并高亮显示
1、目的 可以在osg视图中选中指定模型实体,并高亮显示。共分为两种,一种鼠标点选,一种框选。 2、鼠标点选 2.1 功能说明 生成两组对象,一组cow对象可以被选中,另一组robot不能被选中;点击cow对象被选中高亮,点击robot被选中不高亮;点击空白处,弹出“select nothing!…...
农业大棚智能化改造升级与远程视频监管方案,助力智慧农业建设发展
一、需求分析 随着现代化技术的发展,农业大棚的智慧化也成为当前备受关注的智慧农业发展手段。利用先进的信息化手段来对农业大棚进行管理,采集和掌握作物的生长状况、作业监督、生态环境等信息数据,实现精准操作、精细管理,远程…...
P6入门:项目初始化2-项目详情之日期Date
前言 使用项目详细信息查看和编辑有关所选项目的详细信息,在项目创建完成后,初始化项目是一项非常重要的工作,涉及需要设置的内容包括项目名,ID,责任人,日历,预算,资金,分类码等等&…...
【ubuntu20.04】win10安装ubuntu20.04双系统
win10安装ubuntu20.04双系统: 【ubuntu20.04】win10安装ubuntu20.04双系统:https://www.bilibili.com/video/BV11k4y1k7Li/?spm_id_from333.999.0.0&vd_source66a67b8a0b3c4e03915bf8b3a6ff9a74 ubuntu与windows双系统时间同步: windows认为&…...
使用ffmpeg 压缩视频
我有一批1080p的视频,在网上播放占用空间太大,需要进行压缩以后再上传,下面是记录一下ffmpeg命令的使用情况 原视频大小:288mb --压缩加修改分辨率 640p ffmpeg -y -i C4995.mp4 -vcodec libx264 -crf 18 -s vga C4995\C4995_2.MP4 -y: 强制覆盖 -i :输入文件 -vcodec lib…...
C# , .netWebApi, WPF 用特性实现类似Java 的Ioc 自动装配@Autowired
写C# 一直很羡慕Java的@Autowired 自动装配. 因为C# 必须手动在Ioc里注册 之前用接口实现了自动注册IOC, 总是觉得美中不足, 毕竟没有真正实现用注解/特性实现自动注入, 这次我们来实现一个用特性注入Ioc的扩展方法. namespace MyCode.BLL.Service.Ioc {/// <summary>/…...
3DMAX汽车绑定动画模拟插件MadCar疯狂汽车使用教程
3DMAX汽车绑定动画模拟插件MadCar疯狂的汽车,用于通过模拟控制来快速装配轮式车辆及其动画。这个新版本允许装配任何数量的车轮的车辆,以及包括摩托车在内的任何相互布置。还支持任意数量的拖车。 每个车轮和悬架都有简化的行为设置以及微调,…...
比较PID控制和神经网络控制在机器人臂上的应用
机器人臂是自动化领域中常见的机器人形式,其精确控制对于实现复杂任务具有重要意义。在机器人臂的控制中,PID控制和神经网络控制是两种常用的控制方法。本文将比较PID控制和神经网络控制在机器人臂控制方面的应用,包括控制原理、优缺点以及在…...
ubuntu16.04 交叉编译 mbedtls
在为客户交叉编译项目时需要依赖 mbedtls, 客户的机器是 arm64 的 ubuntu 16.04, 交叉编译过程中遇到几个问题。 首先, mbedtls 需要依赖 python, 在 cmake 的过程中, 如果不是使用系统默认的 cmake 可能会导致,mbedt…...
基于遗传算法优化的直流电机PID控制器设计
PID控制器是工业控制中常用的一种控制算法,通过不断调节比例、积分和微分部分来实现对系统的稳定控制。然而,在一些复杂系统中,传统的PID参数调节方法可能存在局限性。本文将介绍一种基于遗传算法优化的直流电机PID控制器设计方法,…...
大数据-之LibrA数据库系统告警处理(ALM-12036 license文件即将过期)
告警解释 系统每天零点检查一次当前系统中的license文件,如果当前时间距离过期时间不足60天,则license文件即将过期,产生该告警。 当重新导入一个正常license,告警恢复。 说明: 如果当前集群使用节点数小于等于10节…...
如何用Gotham.rs构建RESTful API:10个核心技巧快速上手
如何用Gotham.rs构建RESTful API:10个核心技巧快速上手 【免费下载链接】gotham A flexible web framework that promotes stability, safety, security and speed. 项目地址: https://gitcode.com/gh_mirrors/go/gotham Gotham.rs是一个灵活的Web框架&#…...
Meta烧Token成KPI,OpenClaw引发AI成本结构重塑:不拼算力拼效率
Meta内部烧Token成风近日,据The Information报道,Meta公司内部出现了名为“Claudeonomics”(源自Anthropic旗舰产品Claude)的AI token消费排行榜,由员工自愿在公司内网创建,追踪超8.5万名员工的token使用情…...
Kubernetes 生产环境调试安全最佳实践:2026 年完整指南
Kubernetes 生产环境调试安全最佳实践:2026 年完整指南 摘要:在生产环境中调试 Kubernetes 集群是每个 DevOps 工程师和 SRE 的日常工作。然而,传统的调试方法往往依赖宽泛的集群管理员权限、共享跳板机或长期有效的 SSH 密钥,这些…...
NCE外汇:指尖战场还是桌面指挥中心?深入对比移动端与桌面版交易体验
在快节奏的外汇市场,交易者如同战场上的将领,需要随时洞察瞬息万变的行情,及时下达精确指令。选择合适的交易平台——“武器”和“指挥所”,至关重要。NCE外汇为广大投资者提供了功能强大的桌面平台和灵活便捷的移动应用。两者并非…...
保姆级避坑指南:Redmi AC2100刷Breed和固件时,你可能遇到的5个‘坑’及解决方法
Redmi AC2100刷机实战:5个高频翻车点与深度救援方案 当你盯着论坛里那些"一次成功"的刷机帖时,可能没想到自己会卡在某个莫名其妙的环节。作为刷过三十多台AC2100的老玩家,我见过太多人在相同的地方跌倒——Stok码突然失效、Breed界…...
Linux系统崩溃别慌!手把手教你用Timeshift在Deepin/UOS上快速恢复桌面(含命令行救急指南)
Linux系统崩溃急救手册:Timeshift在Deepin/UOS上的全场景恢复指南 那天下午,我正在赶一份重要文档,Deepin系统突然弹出一个更新提示。像往常一样点击"立即更新"后,屏幕却陷入了黑屏循环重启的噩梦。作为深度系统三年老用…...
用STM32C8T6做个遥控小车?手把手教你驱动PS2手柄(附完整代码)
用STM32C8T6打造智能遥控小车:PS2手柄驱动与电机控制全攻略 1. 项目概述与硬件选型 遥控小车一直是嵌入式开发入门的经典项目,而使用PS2手柄作为控制器则能带来更专业的操控体验。这个项目将STM32C8T6作为主控芯片,通过驱动PS2手柄实现对小车…...
Python 常用的内置函数
Python内置函数速查指南本文整理了Python常用的内置函数,按功能分类为:数学运算类:abs()、round()、pow()等数值计算函数类型转换类:int()、str()、list()等数据类型转换函数序列操作类:len()、sorted()、zip()等序列处…...
form-create-designer进阶玩法:结合CodeMirror实现表单JSON的版本管理与团队协作
form-create-designer团队协作实战:构建企业级表单配置中心 在大型前端项目中,表单往往是业务逻辑最密集、变更最频繁的部分。传统开发模式下,每次表单调整都需要前端工程师手动修改代码,既低效又容易出错。form-create-designer通…...
AD9361官方例程里的Cache操作详解:为什么DMA传输后必须调用Xil_DCacheInvalidateRange?
AD9361高速数据流中的Cache一致性陷阱:从DMA传输异常看Zynq缓存机制 在基于Zynq SoC和AD9361的射频系统中,许多开发者都遇到过这样的诡异现象:PL端通过DMA将ADC采样数据准确写入DDR后,PS端CPU读取的却是一堆"过时"数据。…...
