如何通过Promise顺序调用Fetch API直至响应值更新
用Promise实现持续调用Fetch API直到响应更新
之前用无限同步循环失败的核心原因是:同步代码会阻塞主线程,Fetch的异步响应任务根本没有机会执行完成,导致永远无法检测到响应更新。必须通过异步循环的方式,结合Promise或async/await来实现需求。
方式一:使用async/await + while循环(直观易读)
async function fetchUntilUpdated(url, initialValue) { let lastValue = initialValue; while (true) { try { const response = await fetch(url); if (!response.ok) { throw new Error(`请求失败: ${response.status}`); } const currentValue = await response.json(); // 若返回文本则替换为response.text() if (currentValue !== lastValue) { return currentValue; } lastValue = currentValue; // 延迟1秒后再次请求,可根据需求调整时长 await new Promise(resolve => setTimeout(resolve, 1000)); } catch (err) { console.error('请求出错,稍后重试:', err); await new Promise(resolve => setTimeout(resolve, 2000)); // 出错后延迟更久再重试 } } } // 使用示例 fetchUntilUpdated('你的API地址', null) .then(updatedValue => { console.log('响应已更新:', updatedValue); }) .catch(err => { console.error('最终失败:', err); });
方式二:纯Promise递归实现(无async/await场景)
function fetchUntilUpdated(url, lastValue) { return fetch(url) .then(response => { if (!response.ok) { throw new Error(`请求失败: ${response.status}`); } return response.json(); // 按需替换为response.text()等格式 }) .then(currentValue => { if (currentValue !== lastValue) { return currentValue; } // 延迟后递归调用,继续检测更新 return new Promise(resolve => setTimeout(resolve, 1000)) .then(() => fetchUntilUpdated(url, currentValue)); }) .catch(err => { console.error('请求出错,稍后重试:', err); return new Promise(resolve => setTimeout(resolve, 2000)) .then(() => fetchUntilUpdated(url, lastValue)); }); } // 使用示例 fetchUntilUpdated('你的API地址', null) .then(updatedValue => { console.log('响应已更新:', updatedValue); }) .catch(err => { console.error('最终失败:', err); });
关键注意点
- 异步循环的必要性:同步无限循环会霸占主线程,导致Fetch的异步响应无法被处理,必须用async/await或Promise递归让线程有空闲处理异步任务。
- 值对比逻辑:如果响应是复杂对象,需要改用深对比(比如
JSON.stringify(currentValue) !== JSON.stringify(lastValue),或自定义对比函数)。 - 请求频率控制:加入
setTimeout延迟避免高频请求,保护服务器,延迟时长可根据业务需求调整。 - 错误处理:加入异常捕获,避免单次请求失败导致整个流程中断,可在出错后延迟重试。
内容的提问来源于stack exchange,提问作者Surya K S
相关产品推荐
相关产品推荐

