Simone Nigro
Simone Nigro

Reputation: 4897

Express.js: send response and perform a background task

In Express.js I want to perform a task after send a response.

However, I want to make the response time as fast as possible. I don't need to return the results of this tasks to the client, so I'm trying to return the response immediately.

The task isn't CPU-intensive, then event loop isn't locked by that task.

So, this is my background task:

function backgroundTask() {
   return new Promise(resolve => setTimeout(() => {
      console.log("backgroundTask finished");
      resolve();
   }, 1000));
}

My first attemp is to call backgroundTask function directly:

app.post('/messages', async function (req, res) {
  res.status(200).send({ success: true });
  performBackgroundTasks();
});

the second attemp is to call backgroundTask function into a setTimeout():

app.post('/messages', async function (req, res) {
  res.status(200).send({ success: true });
  setTimeout(() => performBackgroundTasks(), 0);
});

The question is: what is the best method for ensecure that the response is send to the client and the task is berformed in the background?

SIDE NOTE: i know that the "best method" is use Worker Threads, but i just need a simple way for perform a background task.

Upvotes: 4

Views: 6357

Answers (4)

Rashomon
Rashomon

Reputation: 6792

You can use the finish event:

app.use((req, res, next) => {
    res.on('finish', () => {
        console.log('Response has been sent!')
        performBackgroundTasks();
    })
    next()
})

Upvotes: 9

Farnoosh
Farnoosh

Reputation: 197

I'm glad you mentioned that the best method is to spawn a Worker Thread, because it is. I'm of the opinion that you're attempting to do something that simply shouldn't be. sending your res from express is meant to be the final stop of that process and it should contain details about the success of the overall job, so taking further would rob your app of the ability to do that. At least not without making another API call to your dB upon returning to the front end.

if the second step is not important to your users experience why not return with the first res, and trigger another express call from within your promise return on the front page?

Sorry, I'm sure you have a good reason for this, perhaps you can elaborate as to why this is a route you need to take...

Upvotes: 1

Alper Cinar
Alper Cinar

Reputation: 861

Both of your first and second attempt is perfectly suitable for your use case. If your task isn't CPU intensive, using Worker Threads are not even better than your both approach.

Upvotes: 1

devamaz
devamaz

Reputation: 105

You can turn the function to middleware and call next() after your response

Upvotes: 2

Related Questions