【问题标题】:Asynchronously stopping a loop from outside node.js从 node.js 外部异步停止循环
【发布时间】:2022-01-31 01:32:44
【问题描述】:

我正在使用 node.js 14,目前有一个由递归函数和 setTimeout 组成的循环,如下所示:

this.timer = null;

async recursiveLoop() {
   //Do Stuff
   this.timer = setTimeout(this.recursiveLoop.bind(this), rerun_time);
}

但有时这个循环会卡住,我希望它自动注意到它,清理并重新启动。所以我尝试做这样的事情:

this.timer = null;

async recursiveLoop() {
   this.long_timer = setTimeout(() => throw new Error('Taking too long!'), tooLong);
   //Do Stuff
   this.timer = setTimeout(this.recursiveLoop.bind(this), rerun_time);
}

main() {
  //Do other asynchronous stuff
  recursiveLoop()
    .then()
    .catch((e) => {
       console.log(e.message);
       cleanUp();
       recursiveLoop();
    }
}

我不能完全调试它卡在哪里,因为它看起来很随机并且程序在虚拟机上运行。我仍然无法在本地复制它。

这个临时解决方案没有起作用,而是不断使整个 node.js 应用程序崩溃,现在我是一个被卡住的人。我有使用 node.js 14 的限制,不使用微服务,而且我以前从未使用过子进程。我是一个完整的初学者。请帮帮我!

【问题讨论】:

  • “循环卡住”究竟是什么意思?你究竟观察或测量或看到了什么?在这个循环中是否有任何实际的真实代码,因为您向我们展示的内容实际上并没有做任何事情。事实上,它甚至没有记录任何东西。如果涉及真正的代码,那么这可能就是真正的问题所在,我们需要看到它来帮助您解决实际问题。 请向我们展示您的真实代码。仅显示脚手架或伪代码的问题很难或无法回答。
  • 可以用clearTimeout(timer) 停止setTimeout()。真的不知道你还要求什么。
  • setTimeout() 回调中的 throw 不会做任何有用的事情,因为它只会抛出一个空堆栈,因此没有任何东西可以捕获它。
  • 你去哪儿了?试图提供帮助,但您没有回答澄清问题。
  • 我并不担心卡住的部分。我真正想解决的是没有注意到它。我不能透露真实的代码,因为它是公司所有的。脚手架只是为了表明存在一个由 setTimeout 构成的循环。我想让程序注意到它被卡住了,然后抛出一个错误来重新启动它。这种方法的问题是,正如您所说,setTimeout 会抛出一个空堆栈并导致程序崩溃,因为它无法被捕获。

标签: javascript node.js loops asynchronous exception


【解决方案1】:

如果您有一个黑盒代码(这是您提供给我们的所有代码),无法检测到其中的错误,并且您只想知道它何时不再生成结果,您可以将其放入 child_process并要求子进程中的代码在每次运行迭代时向您发送一条消息。然后,在您的主进程中,您可以设置一个计时器,每次从孩子那里收到这些“健康”消息之一时,它都会自行重置。如果计时器在没有收到健康信息的情况下触发,那么孩子一定是“卡住”了,因为您在超时时间内没有收到它的消息。然后,您可以在此时终止子进程并重新启动它。

但是,这是一个巨大的黑客。您应该修复卡住的代码或至少了解发生了什么。可能您正在泄漏内存、文件句柄、数据库句柄、正在运行的代码使用锁和混乱,或者发生了未处理的错误。所有这些都是应该修复的代码的迹象。

【讨论】:

    猜你喜欢
    • 2021-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-11
    • 1970-01-01
    • 2015-02-27
    • 2017-06-16
    • 1970-01-01
    相关资源
    最近更新 更多