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 :)
CodePudding user response:
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.
CodePudding user response:
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