为何fetch()在for循环中执行后脚本中断?如何取消fetch或实现循环调用
批量打印标签的Fetch请求问题解决
一、修复循环中断的问题
你的脚本第一次循环后停止,核心问题有两个:
- 未等待
fetch请求完成就继续执行,且未处理请求失败的异常,一旦请求抛出错误会直接终止整个脚本 - 缺少
sleep函数的定义(原代码中未体现)
修复后的代码示例:
// 定义sleep函数 function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function printing() { for (let w = 0; w < print_labels.length; w++) { const label = `data of the label`; // 替换为实际标签数据 try { // 等待当前打印请求完成后再执行后续逻辑 await fetch('http://111.111.1.111:9100', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: label }); console.log(`${w}. label printed.`); } catch (err) { // 捕获错误避免循环终止,同时记录失败信息 console.error(`${w}. label print failed:`, err); } await sleep(2000); } }; printing();
二、如何取消Fetch请求
如果需要在打印过程中手动终止请求,可使用AbortController API实现:
- 全局声明控制器实例,方便外部触发取消操作
- 将控制器的
signal传入fetch配置项 - 需要取消时调用
abort()方法
示例代码:
const abortController = new AbortController(); const { signal } = abortController; // 示例:通过按钮触发取消(可根据实际场景调整) // document.getElementById('stopPrintBtn').addEventListener('click', () => { // abortController.abort(); // console.log('打印操作已取消'); // }); function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function printing() { try { for (let w = 0; w < print_labels.length; w++) { // 检测到取消信号时提前退出循环 if (signal.aborted) { console.log('收到取消指令,终止打印'); break; } const label = `data of the label`; await fetch('http://111.111.1.111:9100', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: label, signal // 绑定中止信号 }); console.log(`${w}. label printed.`); await sleep(2000); } } catch (err) { if (err.name === 'AbortError') { console.log('打印请求已被取消'); } else { console.error('打印过程出错:', err); } } }; printing();
三、其他批量打印替代方案
如果Fetch的异步模型不符合需求,还可以考虑:
- 使用
XMLHttpRequest替代Fetch,它的中止逻辑更直接(调用abort()方法) - 若打印服务器支持批量接口,直接将所有标签数据打包成一个请求发送,减少请求次数
内容的提问来源于stack exchange,提问作者Denes
相关产品推荐
相关产品推荐

