如何按请求顺序返回多个API查询结果并保持原有数据结构
问题根因
- 内层
delivery.parcels.map(async ()=>{})生成的是一个Promise数组,你没有等待这组Promise全部完成就直接返回了urlData,导致数组中全是pending状态的Promise,而非实际接口返回值 - 外层的
Promise.all(trackingUrl)仅处理了delivery层级的异步,没有覆盖parcel层级的异步请求,自然拿不到解析后的数据
修复后的核心代码
sendTrackingData函数
const sendTrackingData = async (storeKey, deliveries) => { // 外层遍历每个delivery,用Promise.all保证返回顺序和原数组一致 const trackingUrl = await Promise.all(deliveries.map(async (delivery) => { // 内层遍历每个parcel,收集所有API调用的Promise const parcelPromises = delivery.parcels.map(async (parcel) => { const {trackingData} = parcel; const carrier = trackingData.carrier.toLowerCase(); const trackingCode = trackingData.trackingId; // 若需要直接取axios返回的业务数据,可直接return res.data const res = await getTrackingUrl(storeKey, carrier, trackingCode) return res.data }) // 等待当前delivery下所有parcel的请求完成,返回顺序和原parcels数组一致 const urlData = await Promise.all(parcelPromises) console.log(urlData) return urlData })) return trackingUrl };
useEffect调用调整
useEffect不能直接声明为async函数,需要包裹自执行异步函数避免语法警告:
useEffect(() => { const fetchTrackingData = async () => { const test = await sendTrackingData(storeKey, deliveries) console.log(test,'the test url data =========>') // 此处拿到的test结构和deliveries完全匹配,顺序100%对齐原输入数组 } fetchTrackingData() }, [storeKey, deliveries]) // 依赖项可根据你的实际业务调整
逻辑说明
- 两层
Promise.all分别对应delivery、parcel两个层级的异步请求,所有请求完成后才会返回最终结果 Promise.all原生保证返回结果顺序和输入数组顺序完全一致,哪怕后面的请求先响应,输出顺序也不会乱- 如果你要求必须严格按顺序逐个发起请求(而非并发请求、仅保证返回顺序),把map改成for循环逐个await即可
内容的提问来源于stack exchange,提问作者myrdstom
相关产品推荐
相关产品推荐

