如何在Promise.allSettled中实现API调用的间隔执行?
解决方案
原代码的问题在于一次性发起所有API请求,瞬间超过了每秒5次的调用限制,触发了服务端的限流机制,导致连接超时错误。要解决这个问题,需要严格控制请求频率,确保每200毫秒仅发起一次调用。
下面是修改后的串行请求实现,完全匹配每秒5次的限制:
async function getData(endpoints) { const results = []; for (const endpoint of endpoints) { try { const response = await fetch(`${urlStart}/${endpoint}/${urlEnd}`); const data = await response.json(); results.push({ status: 'fulfilled', value: { endpoint, data } }); } catch (error) { results.push({ status: 'rejected', reason: error }); } // 最后一个请求无需等待 if (endpoint !== endpoints[endpoints.length - 1]) { await new Promise(resolve => setTimeout(resolve, 200)); } } return results; }
代码说明:
- 改用
for循环串行处理每个请求,避免一次性发起所有调用 - 每个请求完成后(无论成功或失败),等待200毫秒再处理下一个
- 手动模拟
Promise.allSettled的返回格式,确保和原代码输出结构一致,不影响后续逻辑
如果需要更高效率(比如同时保持最多5个并发请求),可以用批量间隔处理的方式:
async function getData(endpoints) { const results = []; const batchSize = 5; const interval = 1000; // 每1秒处理一批,刚好匹配每秒5次限制 for (let i = 0; i < endpoints.length; i += batchSize) { const batch = endpoints.slice(i, i + batchSize); const batchResults = await Promise.allSettled( batch.map(async endpoint => { const response = await fetch(`${urlStart}/${endpoint}/${urlEnd}`); const data = await response.json(); return { endpoint, data }; }) ); results.push(...batchResults); // 非最后一批则等待1秒 if (i + batchSize < endpoints.length) { await new Promise(resolve => setTimeout(resolve, interval)); } } return results; }
错误说明:
你遇到的连接超时错误(ConnectTimeoutError,错误码UND_ERR_CONNECT_TIMEOUT),本质是服务端检测到你超出调用频率限制后,拒绝了新的连接请求,最终导致客户端连接超时。通过控制请求发起频率,即可避免触发限流机制,解决该问题。
内容的提问来源于stack exchange,提问作者Moshe
相关产品推荐
相关产品推荐

