Reputation: 59
How do we run background tasks in node.js? So that I can perform multiple requests in parallel and simultaneously without blocking the UI. Once a request completes, I can inform the user that the operation is complete and the result is ready. While one request is getting processed, the end user is free to perform other operations as well
Upvotes: 2
Views: 9443
Reputation: 108651
Javascript is single-threaded, so your programs must be asynchronous. Javascript uses events (callbacks, timeouts) to orchestrate the running of many quick function invocations. Nodejs doesn't have a UI to block, but these quick functions can be blocked by a slow function. This asynchronous nature of Javascript applies to both nodejs and browser code.
I believe your question is about how to deal with operations taking a lot of time.
One approach is to break up those operations into a lot of chunks -- quick function calls -- and have each of them use setTimeout()
to start the next one. It's hard to suggest how to do this without understanding your long running function. Here's a question and some answers on the topic. How to break up a long running function in javascript, but keep performance
Summarizing the answer you use this sort of code.
function (data, callbackWhenDone) {
let n = 0
const max = data.length;
const batchSize = 100;
try {
function doBatch () {
let i
for (var i = 0; i < batch && n < max; ++i, ++n) {
doComputation(data[n])
}
if (n < max) setTimeout(doBatch, 0)
else callbackWhenDone(null, data)
}
} catch (error) {
callbackWhenDone(error)
}
doBatch()
}
The setTimeout(fn,0)
at the end of the batch starts the next batch by queuing up a timeout in Javascript's main loop. Other items in that queue get a chance to run. Each batch knows where to start because the doBatch()
function updates n
as it runs. When the whole lot finishes, it invokes the callback you passed in. The callback uses the typical nodejs pattern where the first parameter, if not null, is an error.
Another approach is to use Worker Threads. You can put your computation's Javascript code into a separate Javascript context and have it run. You'll need the knack of passing the data back and forth from the main nodejs process to the thread. Make sure you have a reliable debugger setup before you try this; it can be confusing.
Upvotes: 1