即使事件循环已被占用,如何始终用超时终止NodeJs脚本?

Vik*_*ram 4 javascript selenium node.js

即使事件循环被其他东西占用,是否可以在NodeJS中使用setTimeout终止进程?

例如,说我有如下代码

setTimeout(async () => {
    // Some code I run to gracefully exit my process.
}, timeout);

while (true) {
    let r = 1;
}
Run Code Online (Sandbox Code Playgroud)

我的超时中的回调将永远不会被击中,因为while循环将占据事件循环。有什么办法可以说:“ 不管其他什么,在N秒后执行以下代码?”

我正在写硒测试,但是由于某种原因,测试有时会“卡住”并且永远不会终止。我基本上希望总是在一定的时间后使测试超时,以免我们无法永远运行测试。

谢谢!

Get*_*awn 5

由于JavaScript是单线程的,因此您要做的是使用fork创建一个worker ,这将使它具有多线程的感觉。实际上,这只会给我们两个节点实例,每个实例都有自己的事件循环。此派生将有一个无限循环,您可以通过超时将其杀死。

main.js

const cp = require('child_process')
const path = require('path')

// Create the child
const child = cp.fork(path.join(__dirname, './worker.js'), [])

// Kill after "x" milliseconds
setTimeout(() => {
  process.exit()
}, 5000);

// Listen for messages from the child
child.on('message', data => console.log(data))
Run Code Online (Sandbox Code Playgroud)

接下来,您将设置您的工作程序:

worker.js

let i = 0;
while (true) {
  // Send the value of "i" to the parent
  process.send(i++);
}
Run Code Online (Sandbox Code Playgroud)

孩子可以使用来将有关自身的信息传达给父母process.send(data)

父母可以使用收听孩子的消息child.on('message', ...)


我们可以做的另一件事是,如果您需要主流程来继续做更多的事情,那么杀死孩子而不是主流程。在这种情况下,您可以child.kill()在内部调用setTimeout

const cp = require('child_process')
const path = require('path')

// Create the child
let child = cp.fork(path.join(__dirname, './worker.js'), [])

// Kill after "x" milliseconds
setTimeout(() => {
  child.kill()
}, 5000);
Run Code Online (Sandbox Code Playgroud)

如果eventloop中没有更多事件,则主进程将自动关闭自身,因此我们无需调用process.exit()