中断事件循环处理而不会中断循环

时间:2019-09-03 22:01:22

标签: javascript node.js event-loop

最近我发现自己试图处理大量数据,因此我不得不做一些(使之称为)创造性的编码来获得所需的结果。

我知道处理将是一整天的任务,因此我以一种可以中断和恢复的方式编写了该文件。但是令我感到困扰的是找到了一种处理SIGINT / SIGTERM样式事件的好方法,而又不想破坏我的循环。

顺便说一句,这些显然不是我函数的真实名称

let closed = false;
function* syncGenerator() {
  yield* ~20-trillion-calculated-results;
}
function main() {
  try {
    for ( const value of syncGenerator() ) {
      syncWork(value);
      if (closed) {
        syncGracefulCleanup();
        break;
      }
    }
  } catch ( err ) {
    handleError(err);
  } finally {
    syncGracefulCleanup2();
  }
}
process.on('SIGINT', () => closed = true);

我没有意识到在我仍然处于for循环中时将永远不会处理SIGINT,因此只有在处理完整个数据集之后才会完成(这是非常愚蠢的疏忽,我以为我相信它会的工作原理与Arduino硬件中断相同。

现在我意识到了这一点,我的解决方案是使用微任务async-await技巧将我的一半代码放在刻度的结尾。

let closed = false;
function* syncGenerator() {
  yield* ~20-trillion-calculated-results;
}
async function main() {
  try {
    for ( const value of syncGenerator() ) {
      syncWork(value);
      await new Promise(r => setImmediate(r)); // the new nasty
      if (closed) {
        syncGracefulCleanup();
        break;
      }
    }
  } catch ( err ) {
    handleError(err);
  } finally {
    syncGracefulCleanup2();
  }
}
process.on('SIGINT', () => closed = true);

现在,这可以按我预期的方式工作,并且等待允许循环暂停并允许处理SIGINT / SIGTERM,然后在closed设置为true时进行拾取。好极了.. 但是DAMN看起来很讨厌。 我希望有人可能会提供比这更好的解决方案?

1 个答案:

答案 0 :(得分:1)

您将需要保留该标志,但可以使您的主要逻辑更简单。考虑

selectedItem