如何检测含异步fetch请求的递归JSON处理完成时机?
如何检测递归异步JSON请求的完成时刻
这个问题的核心是用Promise来管理所有异步操作的生命周期,因为递归里的每个fetch都是异步的,我们需要把所有这些异步任务都包裹成Promise,然后等待它们全部完成。下面给你一个具体的实现方案,包含递归逻辑、异步等待和边界处理:
核心思路
- 让递归函数返回Promise,这样每个层级的请求都能被追踪
- 用
Promise.all()等待当前JSON下所有子href对应的递归请求完成 - 加入URL缓存,避免重复请求和循环引用(比如A→B→A的情况)
完整代码示例
// 缓存已处理的URL,防止重复请求和循环引用 const processedUrls = new Set(); // 可选:存储所有处理后的JSON数据,方便后续使用 const processedData = new Map(); async function processNestedJson(url) { // 如果已经处理过这个URL,直接返回已有的结果 if (processedUrls.has(url)) { return processedData.get(url); } processedUrls.add(url); try { // 1. 获取当前URL的JSON数据 const response = await fetch(url); if (!response.ok) { throw new Error(`请求失败: ${response.status} ${response.statusText}`); } const currentData = await response.json(); processedData.set(url, currentData); // 2. 收集所有子href的处理任务 const childTasks = []; // 兼容单个href或href数组的情况 const hrefs = Array.isArray(currentData.href) ? currentData.href : (currentData.href ? [currentData.href] : []); for (const href of hrefs) { childTasks.push(processNestedJson(href)); } // 3. 等待所有子任务完成 await Promise.all(childTasks); return currentData; } catch (err) { console.error(`处理URL ${url} 时出错:`, err); // 标记该URL处理失败,不中断整体流程 processedData.set(url, null); return null; } } // 启动递归处理,并在所有任务完成后执行后续操作 processNestedJson('你的初始JSON URL') .then(() => { console.log('所有JSON数据处理完成!'); // 在这里执行你需要的后续操作,比如渲染数据、写入文件等 console.log('处理结果汇总:', processedData); }) .catch(globalErr => { console.error('全局处理出错:', globalErr); });
关键细节解释
- 递归函数返回Promise:
async函数本身就会返回Promise,所以每次调用processNestedJson都会生成一个可等待的异步任务。 Promise.all()的作用:它会等待传入的所有Promise都resolve后才会resolve,这样就能确保当前JSON下的所有子href请求都完成后,才会标记当前层级处理完成。- URL缓存:
processedUrls集合用来记录已经处理过的URL,避免重复请求相同资源,同时防止循环引用导致的无限递归。 - 错误处理:内部的
try/catch可以捕获单个URL的请求错误,不会因为某个子请求失败导致整个递归链中断;外层的.catch可以处理全局级别的错误。
自定义扩展
如果你不需要收集所有数据,只需要知道什么时候全部完成,可以简化代码,去掉processedData,只保留缓存和递归逻辑即可。如果你的href结构不是数组或单个值,只需要调整hrefs的处理逻辑,适配你的数据格式。
内容的提问来源于stack exchange,提问作者user190794
相关产品推荐
相关产品推荐

