最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How can I always terminate a NodeJs script with a timeout even if the event loop is occupied? - Stack Overflow

programmeradmin0浏览0评论

Is it possible to use setTimeout in NodeJS to terminate a process even if the event loop is being occupied by something else?

For example, say I have code that looks like the following

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

while (true) {
    let r = 1;
}

The callback in my timeout will never be hit since the while loop will occupy the event loop. Is there some way that I can say: "Execute the following code after N seconds regardless of everything else?"

I'm writing selenium tests, but for some reason every once in a while the test will get "stuck" and never terminate. I basically want to always timeout my tests after a certain amount of time so we don't get into the position of tests that run forever.

Thanks!

Is it possible to use setTimeout in NodeJS to terminate a process even if the event loop is being occupied by something else?

For example, say I have code that looks like the following

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

while (true) {
    let r = 1;
}

The callback in my timeout will never be hit since the while loop will occupy the event loop. Is there some way that I can say: "Execute the following code after N seconds regardless of everything else?"

I'm writing selenium tests, but for some reason every once in a while the test will get "stuck" and never terminate. I basically want to always timeout my tests after a certain amount of time so we don't get into the position of tests that run forever.

Thanks!

Share Improve this question asked May 22, 2018 at 22:58 Vikram SundaramVikram Sundaram 4831 gold badge5 silver badges7 bronze badges 2
  • I run process.exit() as part of the "// Some code I run to gracefully exit my process" :) The issue is that I want to run that after a certain amount of time has passed, which is where the difficult in using setTimeout es in. – Vikram Sundaram Commented May 22, 2018 at 23:06
  • Totally! That's what I'm doing currently. The issue is that the setTimeout callback is never run because the event loop is occupied by some synchronous code that never terminates. In the example I gave above, the callabk isn't run because the infinite while loop never gives back control. – Vikram Sundaram Commented May 22, 2018 at 23:10
Add a ment  | 

1 Answer 1

Reset to default 9

Since JavaScript is single threaded, what you are going to want to do is to create a worker using fork, which will give it the feeling of being multi threaded. This will actually just give us two instances of node, each one having their own event loop. This fork will have your endless loop which you can then kill with your timeout.

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))

Next you will setup your worker:

worker.js

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

The child can municate info about itself to the parent using process.send(data).

The parent can listen for messages from the child using child.on('message', ...).


Another thing we can do is kill the child instead of the main process if you need the main process to do more stuff still. And in this case you would call child.kill() inside the setTimeout instead.

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);

If there are no more events in the eventloop, the main process will automatically close itself thus we don't need to call process.exit().

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论