如何使用异步函数转换深度嵌套的动态数据?
问题描述
我有如下结构的旅行对象:
{ name: 'Appropriate Trip Name', mood: 'Provided trip mood', itinerary: [ { destination: 'Destination 1', num_days: 2, recommendations: { day_1: [ { name: 'Day 1, Suggestion 1', justification: 'Justification 1', official_name: 'Official Name 1', }, { name: 'Day 1, Suggestion 2', justification: 'Justification 2', official_name: 'Official Name 2', }, ], day_2: [ { name: 'Day 2, Suggestion 1', justification: 'Justification 1', official_name: 'Official Name 1', }, { name: 'Day 2, Suggestion 2', justification: 'Justification 2', official_name: 'Official Name 2', }, ], }, }, { destination: 'Destination 2', num_days: 1, recommendations: { day_1: [ { name: 'Day 1, Suggestion 1', justification: 'Justification 1', official_name: 'Official Name 1', }, ], }, }, ], }
实际对象中,itinerary数组可包含任意数量的目的地对象,每个recommendations中可包含任意数量的日期,每个日期数组中可包含任意数量的推荐对象。
我需要为每个如下结构的推荐对象添加额外属性:
{ name: 'Day 1, Suggestion 1', justification: 'Justification 1', official_name: 'Official Name 1', }
我有一个异步函数,接收推荐对象并返回增强后的对象(该函数需从多个API获取数据)。尝试过多层循环及各种async/await、Promise.all()组合,但最终得到的itinerary数组中仍存在未解析的嵌套Promise,求最佳实现方案。
解决方案
核心问题在于嵌套异步操作未被完全等待,每层异步遍历都需要用Promise.all()来确保所有子Promise完成后再返回结果。以下是完整的实现方案:
1. 假设异步增强函数
先定义你的异步增强函数(示例):
async function enhanceRecommendation(recommendation) { // 模拟从API获取额外数据 const extraData = await fetch(`https://api.example.com/info?name=${encodeURIComponent(recommendation.official_name)}`).then(res => res.json()); // 返回增强后的对象 return { ...recommendation, rating: extraData.rating, opening_hours: extraData.opening_hours }; }
2. 完整的对象转换函数
通过逐层遍历+Promise.all()确保所有异步操作完成:
async function transformTrip(trip) { // 处理整个行程数组 const updatedItinerary = await Promise.all( trip.itinerary.map(async (destination) => { const updatedRecommendations = {}; // 获取当前目的地的所有日期键(如day_1、day_2) const dayKeys = Object.keys(destination.recommendations); // 遍历每个日期,处理当天的所有推荐 await Promise.all( dayKeys.map(async (dayKey) => { // 对当天的每个推荐调用增强函数,用Promise.all等待全部完成 updatedRecommendations[dayKey] = await Promise.all( destination.recommendations[dayKey].map(enhanceRecommendation) ); }) ); // 返回更新后的目的地对象,保留原有属性 return { ...destination, recommendations: updatedRecommendations }; }) ); // 返回完整的增强后旅行对象 return { ...trip, itinerary: updatedItinerary }; }
3. 使用方式
调用转换函数时需用await或.then()获取结果:
// 假设originalTrip是你的原始旅行对象 const enhancedTrip = await transformTrip(originalTrip); console.log(enhancedTrip); // 此时所有推荐对象都已完成增强,无未解析Promise
关键说明
- 每层异步都要等待:
itinerary.map(async ...)返回的是Promise数组,必须用Promise.all()等待全部解析;同理,每个日期下的推荐列表map(enhanceRecommendation)也需要Promise.all()处理。 - 保留原对象结构:使用扩展运算符
...复制原有属性,避免修改原始对象,保证数据不可变性。 - 错误处理:可根据需求在
enhanceRecommendation或transformTrip中添加try/catch块,处理API请求失败的情况。
内容的提问来源于stack exchange,提问作者dblinkhorn
相关产品推荐
相关产品推荐

