【问题标题】:How to break/cancel forEach loop inside async with timeout如何使用超时中断/取消异步内部的 forEach 循环
【发布时间】:2020-12-26 18:07:05
【问题描述】:

我有一个类似 [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 -------');
});

谁有这个问题的解决方案?

【问题讨论】:

  • 你真的不应该使用异常作为控制流。我建议使用常规循环,您可以轻松地从中中断。
  • 另外,setTimeout 不返回承诺,所以await setTimeout 没有意义。

标签: node.js asynchronous promise


【解决方案1】:

使用这样的递归函数会更好,因为退出带有错误的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 -------');
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-24
    • 2021-05-31
    • 1970-01-01
    • 1970-01-01
    • 2018-10-17
    • 2019-09-04
    • 1970-01-01
    • 2021-12-08
    相关资源
    最近更新 更多