我最近发现自己试图处理大量的数据,我不得不做一些(让我们称之为)创造性的编码,以获得预期的结果。
我知道处理过程将是一个多天的任务,所以我以一种可以被中断和恢复的方式编写它。但让我困惑的是找到了一种处理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硬件中断一样工作。)哦哦。学到的教训。
现在我意识到了这一点,我的解决方案是使用microtask异步等待技巧将我的一半代码放在滴答的末尾。
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,然后如果关闭设置为true,则进行拾取。耶..。但该死的看起来很恶心。我希望有人能找到比这个更好的解决方案?
发布于 2019-09-03 22:15:21
您需要保留标志,但您可以简化您的主要逻辑。考虑一下
let closed = false;
function* syncGenerator() {
  yield* ~20-trillion-calculated-results;
}
function main( generator = syncGenerator() ) 
{
    if (closed) 
    {
      syncGracefulCleanup();
    }
    else 
    {
        // assuming syncWork returns false when 
        // there are no more value
        if ( syncWork( generator.next() ) )
        {
            // next-ish off to the event loop. this is NOT recursive, 
            // even though it may look a bit like it
            setTimeout( () => main(generator), 0 );         
        }
    }
}
process.on('SIGINT', () => close = true);https://stackoverflow.com/questions/57779223
复制相似问题