#javascript #node.js #express #es6-promise #asynchronous-javascript
#javascript #node.js #выразить #es6-обещание #асинхронный-javascript
Вопрос:
Я работаю над проектом, который построен с использованием express и node js. Мне просто нужно вызвать асинхронную функцию внутри функции setTimeout (обратный вызов)
Вот мой файл контроллера
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)
}
}
Вот асинхронная функция в том же контроллере
const updateWhOrders = async (allOrders, req) => {
// Some DB Calls using async await
await SourceOrder.bulkCreate(allOrders.data, { updateOnDuplicate: ["wh_address"] })
}
Теперь я хочу спросить, в чем разница между этими двумя утверждениями
1. setTimeout(() => updateWhOrders(req.Orders, req), 0)
2. updateWhOrders(req.Orders, req)
Я просто хочу вызвать функцию updateWhOrders параллельно перед отправкой ответа обратно в API.
Есть ли какая-либо конкретная причина для использования функции setTimeout? Или, если я опущу функцию setTimeout, она будет вести себя точно так же, как при использовании функции setTimeout?
Насколько я понимаю, если я опущу функцию setTimeout, она будет работать в фоновом режиме, возвращая обещание. Что, если я вызову функцию (updateWHOrders) внутри функции setTimeout. В чем выгода? Пожалуйста, поправьте меня, если я ошибаюсь.
Заранее благодарю вас 🙂
Комментарии:
1. Использование
setTimeout(func,0)
просто приведет к тому, что узел пропустит эту строку на данный момент, запустите весь синхронный код, затем запуститеfunc
.2.
if I omit setTimeout function it will run in the background by returning a promise
—> Нет, он все равно возвращает обещание (этоasync
функция).3. @JeremyThille. Он не обрабатывает функцию в фоновом режиме, возвращая обещание? поскольку асинхронная функция всегда возвращает обещание
4. Если я опущу setTimeout, то он не будет вызывать func позже, выполнив весь оставшийся код?
5. Что такое
rows
? Это нигде не определено…
Ответ №1:
Вы не должны использовать setTimeout
здесь: обратный вызов будет выполняться не параллельно, а позже, после выполнения остальной части синхронного кода.
Вместо этого, если это единственная асинхронная задача, которая должна выполняться перед вызовом res.status(200)
, используйте await
:
await updateWhOrders(req.Orders, req);
Если у вас больше асинхронных задач, и они независимы друг от друга, так что они могут выполняться в любом порядке — и не нужно ждать результата другого — тогда используйте Promise.all
:
await Promise.all([
updateWhOrders(req.Orders, req),
anotherAsyncFunc(),
yetAnotherAsyncFunc()
]);
Разница с setTimeout
Вы просили указать разницу между этими операторами:
setTimeout(() => updateWhOrders(req.Orders, req), 0)
updateWhOrders(req.Orders, req)
Первая функция не будет вызываться updateWhOrders
сейчас, но запланирует ее выполнение после выполнения всего синхронного кода. Это может быть сразу после выполнения следующего await
, или, если его нет, после return
выполнения. Сначала стек вызовов должен стать пустым и только после updateWhOrders
этого может быть выполнен.
Второй будет выполнен updateWhOrders
немедленно.
Ни один из них не использует тот факт, что updateWhOrders
возвращает обещание, и поэтому этот аспект рассматривается недостаточно хорошо. Вы захотите узнать, когда асинхронный вызов внутри updateWhOrders
завершит свою работу, и для этого вам нужно что-то сделать с возвращенным обещанием. Вот почему вы должны использовать либо .then
, await
, Promise.all
, … , либо все, что связано с этим обещанием.
Комментарии:
1. Спасибо. Но updateWHOrders — это независимая функция, которую необходимо вызывать, не блокируя остальную часть кода. Если я использую await, он выполнит его и будет ждать его завершения. Вместо этого я хочу выполнять параллельно, не дожидаясь его завершения
2. Итак, вы хотите
res.status(200).json()
, чтобы вас вернули до того, как этоupdateWHOrders
будет вызвано? Вы уверены? Пожалуйста, объясните, с чем вы хотите, чтобы это было «параллельно»…3. Нет. Я просто хочу завершить функцию updateWHOrders непосредственно перед res.status(200)
4. Если вы хотите
updateWHOrders
работать «параллельно» (в JS такого нет, но есть асинхронность) с другими асинхронными задачами , тогда выберитеPromise.all
версию и вызовите все другие асинхронные функции в том массиве, который передается ему в качестве аргумента, что является альтернативой, которую я ввел в свой ответ. Вам необходимоawait
убедиться, что все эти «параллельные» задачи завершены доreturn
выполнения.5. ОК. Спасибо. Но не могли бы вы, пожалуйста, рассказать мне о разнице между двумя синтаксисами функции updateWHOrders, которые я уже упоминал в постановке вопроса
Ответ №2:
Хассам. setTimeout
основная функция заключается в вызове функции asynchronously
. Он возвращает promise
и является заменой new Promise
функции в NodeJS. Отвечая на ваш вопрос, здесь вы не хотите updateWhOrders
блокировать функцию и хотите запустить ее в отдельном потоке, не блокируя другую часть кода. Хотя NodeJS является однопоточным языком, он использует один и тот же поток для обработки синхронных и асинхронных вызовов, и они обрабатываются с помощью цикла событий. Чтобы узнать больше о цикле событий, вы можете посмотреть это видео: https://youtu.be/8aGhZQkoFbQ
Комментарии:
1. Спасибо, но мне нужно больше информации