node.js - 如何使用超时中断/取消异步内部的 forEach 循环
问题描述
我有一个像 [1,2,3,4,5,6,7,8,9,10] 这样的数组。我想运行这个数组的 forEach,每个项目都有超时 1s,如果当前项目符合条件,则中断 foreach。我发现仅适用于异步的代码:
var BreakException = {};
try {
[1,2,3,4,5,6,7,8,9,10].forEach(function(el) {
console.log(el);
if (el === 6) throw BreakException;
});
} catch (e) {
if (e !== BreakException) throw e;
}
但是当我使用异步时,它会运行所有项目:
var BreakException = {};
let list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var realtimePromise = new Promise((resolve, reject) => {
list.every(async(item, pKey) => {
await setTimeout(function() {
try {
console.log(item);
if (item === 6) throw BreakException;
} catch (e) {
if (e !== BreakException) throw e;
}
}, 2000 * pKey);
});
});
realtimePromise.then(() => {
console.log('------- End loop -------');
});
有人有这个问题的解决方案吗?
解决方案
使用这样的递归函数会更好,因为退出forEach
带有错误的循环不是一个好习惯:
const list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const realtimePromise = (index = 0) => {
return new Promise((resolve, reject) => {
if (index > list.length - 1) reject(new Error('Item not in list'));
const currentItem = list[index];
console.log(currentItem);
if (currentItem === 6) resolve(currentItem);
else setTimeout(() => {
resolve(realtimePromise(++index));
}, 2000);
});
}
realtimePromise().then(() => {
console.log('------- End loop -------');
});
推荐阅读
- firebase - 尝试将颤振与firebase消息ios集成时出现白屏
- sql-server - 像 `User::filePath` 这样的变量如何传递给由 SQL 代理作业运行的 SSIS 包中的脚本?
- c# - 如何修复命名空间“WebApplication1”中不存在类型或命名空间“App_Code”
- javascript - 尽管导航到多个 html/js 文件,但当我的站点加载并获取任何传入消息时,我可以使用 javascript 连接到 MQTT 代理吗?
- rest - 不向客户端返回任何内容的 POST 方法是否需要 Accept 标头?
- spring-boot-actuator - 如何在 SpringBoot Admin UI 中启用关闭功能?
- tableau-api - 如何合并 2 个参数值以过滤表格中的字段?
- go - Golang Alloc 和 HeapAlloc vs pprof 差异较大
- dask - 如何在 DASK 中批量调度 dask_jobqueue 作业而不是并发?
- python - Kivy Video 类 rtsp 流在其他电脑上不起作用