JS遍历数组时发起HTTP请求返回含请求结果数组的实现方法
问题描述
现有如下待处理数组:
const arr = [{key1: 'value1', key2: 'value2'}, {key1: '', key2: 'value2'}, {key1: 'value1', key2: 'value2'}]
核心需求:
- 遍历数组,检查每一项的
key1字段是否存在有效值 - 若
key1为空/无有效值,发起HTTP请求获取对应值填充 - 最终返回所有项
key1均具备有效值的新数组,不修改原数组
原有无法正常运行的实现代码如下:
const arr = [{key1: 'value1', key2: 'value2'}, {key1: '', key2: 'value2'}, {key1: 'value1', key2: 'value2'}]; arr.map(i => { if (!i.key1) { const value = getValueFromHttpRequest(); return { ...i, key1: value } } return i; })
预期返回的正确结果格式:
[{key1: 'value1', key2: 'value2'}, {key1: 'valueFromHttpRequest', key2: 'value2'}, {key1: 'value1', key2: 'value2'}]
问题原因
原有代码失效的核心原因是HTTP请求属于异步操作:
- 原生同步
map遍历不会等待内部异步请求执行完成 - 直接调用
getValueFromHttpRequest()拿到的是异步请求的Promise对象,并非接口返回的实际值,因此无法得到预期填充结果。
可行实现方案
以下方案默认getValueFromHttpRequest为返回Promise的异步请求函数(即常规fetch/axios封装的接口方法),根据请求策略分为两种实现:
方案1:并行请求(性能优先,推荐无并发限制场景使用)
所有需要补值的项同时发起请求,整体耗时为单个最慢请求的时长,执行效率最高:
async function fillMissingKey1(originArr) { // 等待所有项处理完成(含异步请求) const result = await Promise.all( originArr.map(async (item) => { // key1已有有效值,直接返回浅拷贝的项,避免修改原数组 if (item.key1?.trim()) { return { ...item } } // 等待请求返回有效值后再组装新项 const fillValue = await getValueFromHttpRequest() return { ...item, key1: fillValue } }) ) return result } // 调用方式 // 支持顶层await的环境可直接使用 const finalArr = await fillMissingKey1(arr) // 不支持顶层await的环境用.then回调获取结果 fillMissingKey1(arr).then(finalArr => { console.log(finalArr) // 此处拿到符合预期的最终数组 })
方案2:顺序请求(适合接口有并发限制的场景)
逐个处理数组项,等上一项的请求完成后再发起下一个请求,避免请求并发过高触发接口限流:
async function fillMissingKey1Sequentially(originArr) { const result = [] for (const item of originArr) { if (item.key1?.trim()) { result.push({ ...item }) continue } // 等待当前请求完成后再进入下一轮循环 const fillValue = await getValueFromHttpRequest() result.push({ ...item, key1: fillValue }) } return result } // 调用方式和并行方案完全一致 const finalArr = await fillMissingKey1Sequentially(arr)
补充说明:如果HTTP请求需要根据当前项的其他字段(比如
key2)查询对应的key1值,只需要给请求方法传入对应参数即可,例如await getValueFromHttpRequest(item.key2)。所有返回项都做了浅拷贝,不会修改原始数组的数据,避免副作用。
内容的提问来源于stack exchange,提问作者As above so below
相关产品推荐
相关产品推荐

