fetch请求后执行逻辑:如何等待counter全部fetch完成后操作及写法是否规范
实现方案
你遇到的核心问题是原counter函数没有返回Promise,外层无法感知内部所有异步操作的完成时机,同时递归逻辑没有对fetch的异步状态做追踪,没法在全部请求结束后触发回调。
这里优先推荐更易维护的async/await版本,保证前一次请求处理完成后再间隔1秒发起下一次,所有请求完成后自动执行后续逻辑:
var cdict = new Map(); fetch("randomurl") .then(res => res.json()) .then(async data => { for (const obj of data.result) { // 往Map cdict插入数据的逻辑 } // 等待counter内部所有请求执行完成 await counter(0); console.log(cdict); // 后续要执行的逻辑直接写在这里即可 }); const ccount = 10; async function counter(cnt) { // 递归终止条件 if (cnt >= ccount) return; // 等待1秒 await new Promise(resolve => setTimeout(resolve, 1000)); // 发起当前请求并等待处理完成 try { const res = await fetch(someurl); const data = await res.json(); for (const obj of data.result) { // 处理数据、操作cdict的逻辑 } } catch (err) { console.log(err); } // 递归执行下一次请求 await counter(cnt + 1); }
如果你需要严格每隔1秒发起一次请求,不管前一次请求是否返回,可以用下面的批量创建定时请求的版本:
var cdict = new Map(); fetch("randomurl") .then(res => res.json()) .then(async data => { for (const obj of data.result) { // 往Map cdict插入数据的逻辑 } await counter(); console.log(cdict); }); const ccount = 10; function counter() { const requestPool = []; for (let i = 0; i < ccount; i++) { // 每个请求延迟对应秒数发起 const req = new Promise(resolve => setTimeout(resolve, i * 1000)) .then(() => fetch(someurl)) .then(res => res.json()) .then(data => { for (const obj of data.result) { // 处理数据逻辑 } }) .catch(err => console.log(err)); requestPool.push(req); } // 返回所有请求完成的Promise return Promise.all(requestPool); }
原间隔调用写法的合理性分析
原写法不合理,存在以下问题:
- 无返回值,外层无法监听异步操作完成状态,你原本写的
counter(0).then()完全不会生效 - 没有等待fetch请求完成就触发下一次递归,如果某个请求耗时超过1秒,会出现响应顺序和发起顺序不一致的问题,如果你对数据处理顺序有要求会直接出错
- 无全局的异常捕获和状态追踪,无法判断是否有请求失败、是否全部执行完成
- 纯副作用递归,内存占用和执行逻辑都不可控
内容的提问来源于stack exchange,提问作者jeea
相关产品推荐
相关产品推荐

