嵌套for循环执行卡顿,无法输出完成提示
问题描述
我有一个项目需要从关联关系中提取ID:先将tickets存入数组,再循环遍历tickets以获取关联的timelog的ID。代码前半部分可正常运行,但提取到第17个ticket时出现卡顿,控制台始终无法输出"done"提示。
Ticket 数据示例
{"id":164563,"subject":"License Upgrade","readonly":false,"messageCount":4,"previewText":"...","originalRecipient":null,"responseTimeMins":39,"resolutionTimeMins":540,"imagesHidden":false,"isRead":true,"spam":{"reports":null,"isSpam":false,"score":0,"reasons":null},"spam_score":0,"spam_rules":null,"customer":{"id":459947,"type":"customers"},"contact":{"id":459351,"type":"contacts"},"inbox":{"id":619,"type":"inboxes"},"agent":{"id":498221,"type":"users"},"status":{"id":5,"type":"ticketstatuses"},"priority":{"id":1585,"type":"ticketpriorities"},"source":{"id":1,"type":"ticketsources"},"type":{"id":2549,"type":"tickettypes"},"createdBy":{"id":459947,"type":"customers"},"updatedBy":{"id":498221,"type":"users"},"messages":[{"id":407225,"type":"messages"},{"id":420758,"type":"messages"},{"id":420918,"type":"messages"},{"id":420923,"type":"messages"},{"id":433645,"type":"messages"},{"id":433688,"type":"messages"},{"id":434765,"type":"messages"},{"id":434822,"type":"messages"},{"id":434958,"type":"messages"},{"id":435576,"type":"messages"},{"id":435582,"type":"messages"},{"id":437807,"type":"messages"},{"id":446866,"type":"messages"},{"id":446867,"type":"messages"},{"id":446871,"type":"messages"},{"id":446872,"type":"messages"},{"id":446873,"type":"messages"}],"customfields":[{"id":66,"type":"customfields","meta":{"value":""}},{"id":67,"type":"customfields","meta":{"value":""}},{"id":60,"type":"customfields","meta":{"value":null}},{"id":68,"type":"customfields","meta":{"value":""}},{"id":64,"type":"customfields","meta":{"value":""}},{"id":65,"type":"customfields","meta":{"value":""}},{"id":63,"type":"customfields","meta":{"textValue":"None","value":170}}],"tags":[{"id":218,"type":"tags"}],"files":[{"id":70784,"type":"files"}],"timelogs":[{"id":16302,"type":"timelogs"},{"id":16486,"type":"timelogs"},{"id":16574,"type":"timelogs"}],"businesshours":{"id":6,"type":"businesshours"},"company":{"id":893,"type":"companies"},"createdAt":"2023-01-14T03:06:59Z","updatedAt":"2023-01-17T13:57:29Z","state":"active"}
原代码片段
console.log(`${tickets.length} tickets to search...`) for (let i = 0; i < tickets.length; i++) { const ticket = tickets[i]; console.log(i + 1); const ticketTimeLogs = ticket.timelogs; console.log(`Getting ${ticketTimeLogs.length} timelogs for ticket ${ticket.id}...`) for (let j = 0; j < ticketTimeLogs.length; j++) { const ticketTimeLog = ticketTimeLogs[j]; console.log(`Got timelog ${ticketTimeLog.id}`); timelogIds.push(ticketTimeLog.id); continue; } } console.log("done");
控制台输出
Result Size: 1 | Has More Pages: false 25 tickets to search... 1 Getting 3 timelogs for ticket 164563... Got timelog 16302 Got timelog 16486 Got timelog 16574 2 Getting 2 timelogs for ticket 164602... Got timelog 16163 Got timelog 16272 3 Getting 1 timelogs for ticket 164621... Got timelog 16630 4 Getting 1 timelogs for ticket 164810... Got timelog 16629 5 Getting 1 timelogs for ticket 175606... Got timelog 16252 6 Getting 3 timelogs for ticket 175714... Got timelog 16246 Got timelog 16247 Got timelog 16472 7 Getting 1 timelogs for ticket 182857... Got timelog 16274 8 Getting 1 timelogs for ticket 182971... Got timelog 16459 9 Getting 2 timelogs for ticket 183155... Got timelog 16409 Got timelog 16411 10 Getting 1 timelogs for ticket 183241... Got timelog 16279 11 Getting 1 timelogs for ticket 183732... Got timelog 16344 12 Getting 2 timelogs for ticket 184405... Got timelog 16410 Got timelog 16460 13 Getting 1 timelogs for ticket 184406... Got timelog 16346 14 Getting 2 timelogs for ticket 184957... Got timelog 16484 Got timelog 16607 15 Getting 2 timelogs for ticket 185148... Got timelog 16466 Got timelog 16594 16 Getting 1 timelogs for ticket 185191... Got timelog 16468 17
问题原因分析
从输出可以看出,循环执行到第17个ticket时直接终止,没有继续后续操作,大概率是这个ticket的timelogs字段存在异常:
- 可能是
timelogs为undefined或null,导致读取ticketTimeLogs.length时抛出未捕获的错误,中断整个循环 - 可能是
timelogs是一个异常大的数组或循环引用结构,导致内层循环无法结束 - 可能是该ticket的
timelogs中存在格式异常的元素,访问id时触发错误
解决方案
1. 增加错误捕获与数据校验
修改代码,加入try-catch块捕获单个ticket的处理错误,同时校验timelogs的有效性,避免单个异常影响整个循环:
console.log(`${tickets.length} tickets to search...`) const timelogIds = []; for (let i = 0; i < tickets.length; i++) { try { const ticket = tickets[i]; console.log(i + 1); // 校验timelogs是否为有效数组 if (!ticket.timelogs || !Array.isArray(ticket.timelogs)) { console.log(`Ticket ${ticket.id} 无有效timelogs,跳过...`); continue; } const ticketTimeLogs = ticket.timelogs; console.log(`获取ticket ${ticket.id}的${ticketTimeLogs.length}条timelog...`) for (let j = 0; j < ticketTimeLogs.length; j++) { const ticketTimeLog = ticketTimeLogs[j]; // 校验timelog是否有有效id if (ticketTimeLog?.id) { console.log(`获取到timelog ID: ${ticketTimeLog.id}`); timelogIds.push(ticketTimeLog.id); } else { console.log(`Ticket ${ticket.id}的第${j+1}条timelog无有效ID,跳过...`); } } } catch (err) { console.error(`处理第${i+1}个ticket时出错:`, err); } } console.log("done"); console.log(`共提取到${timelogIds.length}个timelog ID`);
2. 排查第17个ticket的异常数据
直接打印第17个ticket的完整数据,确认timelogs字段的状态:
// 数组索引从0开始,第17个ticket对应索引16 console.log("第17个ticket数据:", tickets[16]);
3. 优化遍历方式(可选)
使用forEach替代for循环,代码更简洁,且单个元素的处理错误不会中断整个遍历:
console.log(`${tickets.length} tickets to search...`) const timelogIds = []; tickets.forEach((ticket, index) => { try { console.log(index + 1); if (!ticket.timelogs || !Array.isArray(ticket.timelogs)) { console.log(`Ticket ${ticket.id} 无有效timelogs,跳过...`); return; } console.log(`获取ticket ${ticket.id}的${ticket.timelogs.length}条timelog...`) ticket.timelogs.forEach(timelog => { if (timelog?.id) { console.log(`获取到timelog ID: ${timelog.id}`); timelogIds.push(timelog.id); } else { console.log(`Ticket ${ticket.id}的timelog无有效ID,跳过...`); } }); } catch (err) { console.error(`处理第${index+1}个ticket时出错:`, err); } }); console.log("done"); console.log(`共提取到${timelogIds.length}个timelog ID`);
内容的提问来源于stack exchange,提问作者Jonathan George
相关产品推荐
相关产品推荐

