1

I have this piece of code that runs on a large array:

for (i = 0; i < cars.length; i++) { 
    cars[i] = some_function(cars[i]) ;
}

and I should run this code in intervals without blocking the event loop. What is a proper way to do it?

4
  • 1
    you want setInterval? Commented Apr 14, 2016 at 17:41
  • 1
    Using recursion and setTimeout you will get expected result. Please look at this answer Commented Apr 14, 2016 at 17:45
  • Unfortunately you can't, node.js is single threaded, so every big task will block the event loop. if you want to run large task, you should do it in a new process. Commented Apr 14, 2016 at 17:48
  • Recursion will not help as it also blocks the event loop, and @AlexanderMac this is only half the truth as you maybe can chunk your big task and give control back. Commented Apr 14, 2016 at 17:51

2 Answers 2

3

For the part not blocking the event loop you have two options, maybe even more:

  1. Load off your work to a child process or a worker
  2. Chunk your processing inside some_function with process.nextTick to give control back to the event loop between chunks

If chunking is possible you have to figure out as there are no details of your function.

For the part of intervals you should wrap the code inside a setInterval.

Sign up to request clarification or add additional context in comments.

2 Comments

I use Express.js framework,where should i start a child process,in app.js right? should i start a child process do the job and kill it or start a child process that runs in background and as a demon and do the job with it in intervals? which one is better?
In your case it seems better to just spawn a child process and kill it afterwards. But that depends on the interval timeout. If you have many offloaded tasks that also run in parallel and often, you can probably enhance performance by a pool of workers.
3

There is an excellent asynchronous-handler library called Bluebird that's emerging as the main tool for NodeJS async coordination.

Bluebird has a really useful method pair designed to work with arrays: map and mapSeries. It's simple to use, lets you iterate across arrays without blocking the event loop, and makes the code very readable:

var Promise = require('bluebird'),
    cars = ['a', 'b', 'c'];

// Iterate across cars without blocking the event loop. Each
// callback will be made in PARALLEL:
// @see http://bluebirdjs.com/docs/api/promise.map.html
Promise.map(cars, function(car) {
    console.log("I'm logging car ' + car + ' but could be any complex code...');
});

// Iterate across cars without blocking the event loop. Each
// callback will be made in SERIES. An item will be fully processed
// before moving on to the next:
// @see http://bluebirdjs.com/docs/api/promise.mapseries.html
Promise.mapSeries(cars, function(car) {
    console.log("I'm logging car ' + car + ' but could be any complex code...');
});

1 Comment

Wow, Bluebird. I remember that. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.