1

I am working on a project which is built using express and node js. I just need to call the async function inside the SetTimeout function (callback)

Here is my Controller File

module.exports.create = async (req, res) => {
  try {
    // Some DB Calls

    setTimeout(() => updateWhOrders(req.Orders, req), 0)

    // Some DB Calls

    return res.status(200).json({ data , msg: "record created successfully", success: true })
  } catch (error) {
    if (error?.message?.includes("Validation error")) {
      return handleErr({ message: "This supplier order id has already been added. Please refresh the page and check further down the screen." }, res)
    }
    return handleErr(error, res)
  }
}

Here is the async function in the same controller

const updateWhOrders = async (allOrders, req) => {
  // Some DB Calls using async await
  await SourceOrder.bulkCreate(allOrders.data, { updateOnDuplicate: ["wh_address"] })
}

Now I want to ask the difference between these two statements

1. setTimeout(() => updateWhOrders(req.Orders, req), 0)
2. updateWhOrders(req.Orders, req)

I just want to call the updateWhOrders function parallel before sending the response back to the API.

Is there any specific reason to use the setTimeout function? Or if I omit the setTimeout function it will behave exactly the same as using setTimeout function?

According to my understanding if I omit setTimeout function it will run in the background by returning a promise. What if I call function(updateWHOrders) inside setTimeout function. What is the benefit? Please correct me if I am wrong.

Thank you in Advance :)

Hassam Saeed
  • 385
  • 5
  • 24
  • 1
    Using `setTimeout(func,0)` will simply cause Node to skip this line for now, run all the synchronous code, then run `func`. – Jeremy Thille Dec 05 '21 at 13:16
  • `if I omit setTimeout function it will run in the background by returning a promise` --> No, it returns a Promise anyway (it's an `async` function). – Jeremy Thille Dec 05 '21 at 13:19
  • @JeremyThille. It does not process the function in the background by returning a promise? as async function always returns the promise – Hassam Saeed Dec 05 '21 at 13:21
  • If I omit the setTimeout then it will not call func later by executing all the remaining code? – Hassam Saeed Dec 05 '21 at 13:25
  • What is `rows`? It is nowhere defined... – trincot Dec 05 '21 at 13:40
  • @trincot ignore it. – Hassam Saeed Dec 05 '21 at 13:41
  • In that case, could you remove anything from your question that is not relevant? – trincot Dec 05 '21 at 13:42
  • @trincot Sure. i will – Hassam Saeed Dec 05 '21 at 13:42
  • Also, I see no code that sets, or modifies `supplierOrder`, yet you report it as the result. Then there is the test on `existingSupplierOrders.length`... As there is no code that sets or modifies `existingSupplierOrders`, why is that test there? It seems there is a lot of noise in this question that makes it hard to see what you are really after. – trincot Dec 05 '21 at 13:44
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/239842/discussion-between-hassam-saeed-and-trincot). – Hassam Saeed Dec 05 '21 at 13:49

2 Answers2

1

You shouldn't use setTimeout here: it will not execute the callback in parallel, but later, after the rest of the synchronous code has executed.

Instead, if it is the only asynchronous task that needs to happen before the call of res.status(200), then use await:

await updateWhOrders(req.Orders, req);

If you have more asynchronous tasks, and they are independent of each other such that they could execute in any order -- and don't have to wait for the other's result -- then use Promise.all:

await Promise.all([
    updateWhOrders(req.Orders, req),
    anotherAsyncFunc(),
    yetAnotherAsyncFunc()
]);

Difference with setTimeout

You asked for the difference between these statements:

setTimeout(() => updateWhOrders(req.Orders, req), 0)
updateWhOrders(req.Orders, req)

The first will not call updateWhOrders now, but will schedule it for execution after all synchronous code has executed. This could be just after the next await has executed, or if there is none, after the return has executed. The call stack must become empty first and only then updateWhOrders can get executed.

The second will execute updateWhOrders immediately.

Neither use the fact that updateWhOrders returns a promise, and so this aspect is not well dealt with. You'll want to know when the asynchronous call inside updateWhOrders has finished its job, and for that you need to do something with the returned promise. That's why you should use either .then, await, Promise.all, ...or anything that deals with that promise.

trincot
  • 317,000
  • 35
  • 244
  • 286
  • Thank you. But updateWHOrders is the independent function that needs to be called without blocking the rest of the code. If I use await then it will execute it and wait for it to complete. Instead, I want to execute in parallel without waiting to complete it – Hassam Saeed Dec 05 '21 at 14:11
  • So you want `res.status(200).json()` to be returned before that `updateWHOrders` is called? Are you sure? Please explain what it is that you want it to be in "parallel" with... – trincot Dec 05 '21 at 14:16
  • No. I just want to complete the function updateWHOrders just before res.status(200) – Hassam Saeed Dec 05 '21 at 14:18
  • If you want `updateWHOrders` to run in "parallel" (there is no such thing in JS, but there is asynchrony) with *other asynchronous tasks*, then go for the `Promise.all` version, and call all other async functions in that array that is passed to it as argument, which is the alternative I put in my answer. You need `await` to ensure all those "parallel" tasks have finished before the `return` is executed. – trincot Dec 05 '21 at 14:20
  • Ok. Thank you. But can you please tell me the difference between the two syntax of the function updateWHOrders that i mentioned already in the question statement – Hassam Saeed Dec 05 '21 at 14:22
  • Added a section to my answer. – trincot Dec 05 '21 at 14:28
-1

Hassam. setTimeout main function is to call a function asynchronously. It returns a promise and is the replacement of the new Promise function in NodeJs. Coming towards your question, here you don't want to make the updateWhOrders function-blocking and want to run it in a seperate thread without blocking other part of code. Although NodeJs is a single-threaded language it uses the same thread to handle synchronus and asynchronous calls and they are handled using Event Loop. To learn more about Event Loop you may watch this video: https://youtu.be/8aGhZQkoFbQ