for循环中接口调用
起因:同事发现一个外层数组为0,但长度为2,这种“奇怪”的数据结构
正确的数据结构
原因:循环中执行异步请求导致的
复现业务代码:
//模拟ajax请求
function ajax(){ let data = [{name:'小明',age:22},{name:'小红',age:18}] return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(data) },200) }) } //因业务要求,循环中调用接口 function run(){ let userList = [{id:1},{id:2}]; let list = []; userList.forEach((item)=>{ ajax().then((res)=>{ list.push(res) }) }) console.log(list) } run()
解决方式一 :Promise.all
function ajax() { let data = [{ name: '小明', age: 22 }, { name: '小红', age: 18 }] return new Promise((resolve, reject) => { setTimeout(() => { resolve(data) }, 200) }) } 创建Promise方法 function createPromise() { let promise = new Promise((resolve, reject) => {
//将业务接口的返回值,resolve进去 ajax().then((res) => { resolve(res) }) }) return promise } function run() { let userList = [{ id: 1 }, { id: 2 }]; let list = []; let resList = []; userList.forEach((item) => { list.push(createPromise()) }) Promise.all(list).then((res) => { resList = res }) } run()
缺点:
1.Promise.all得等所有请求成功,才能返回,会遇到阻塞问题
2.Promise.all得等所有请求响应,响应时间太长问题
解决方式二 :递归调用接口
function ajax() { let data = [{ name: '小明', age: 22 }, { name: '小红', age: 18 }] return new Promise((resolve, reject) => { setTimeout(() => { resolve(data) }, 200) }) }
递归终止条件,数组长度小于 async function run(length, arr) { const res = await ajax(); arr.push(res) if (length> 1) { await run(length- 1, arr) } return arr } async function getResult() { let userList = [{ id: 1 }, { id: 2 }]; let res = await run(userList.length, []); } getResult()
优点:恰恰解决了Promise.all的痛点
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)