【问题标题】:call Async function inside setTimeout在 setTimeout 中调用 Async 函数
【发布时间】:2022-01-11 00:29:45
【问题描述】:

我正在开发一个使用 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)

我只想在将响应发送回 API 之前并行调用 updateWhOrders 函数。

使用 setTimeout 函数有什么特别的原因吗?或者如果我省略 setTimeout 函数,它的行为会与使用 setTimeout 函数完全相同?

根据我的理解,如果我省略 setTimeout 函数,它将通过返回一个承诺在后台运行。如果我在 setTimeout 函数中调用 function(updateWHOrders) 会怎样。有什么好处?如果我错了,请纠正我。

提前谢谢你:)

【问题讨论】:

  • 使用setTimeout(func,0)只会让Node暂时跳过这一行,运行所有同步代码,然后运行func
  • if I omit setTimeout function it will run in the background by returning a promise --> 不,它无论如何都会返回一个 Promise(它是一个 async 函数)。
  • @JeremyThille。它不会通过返回一个promise来处理后台的函数吗?因为异步函数总是返回承诺
  • 如果我省略了 setTimeout 那么它不会通过执行所有剩余的代码来调用 func 吗?
  • 什么是rows?它没有定义...

标签: javascript node.js express es6-promise asynchronous-javascript


【解决方案1】:

你不应该在这里使用setTimeout:它不会并行执行回调,而是稍后,在其余同步代码执行之后。

相反,如果是在调用res.status(200)之前需要发生的唯一异步任务,则使用await

await updateWhOrders(req.Orders, req);

如果您有更多异步任务,它们是相互独立的,因此它们可以按任何顺序执行——并且不必等待对方的结果——然后使用 @ 987654325@:

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 返回承诺的事实,因此这方面没有得到很好的处理。你会想知道异步调用 inside updateWhOrders 什么时候完成了它的工作,为此你需要对返回的 Promise 做一些事情。这就是为什么你应该使用.thenawaitPromise.all,...或任何与该承诺有关的东西。

【讨论】:

  • 谢谢。但是 updateWHOrders 是独立的函数,需要在不阻塞其余代码的情况下调用。如果我使用 await 那么它将执行它并等待它完成。相反,我想并行执行而不等待完成它
  • 所以您希望在调用updateWHOrders 之前返回res.status(200).json()?你确定吗?请解释您希望它与...“平行”的是什么
  • 没有。我只想在 res.status(200) 之前完成函数 updateWHOrders
  • 如果你想让updateWHOrders其他异步任务“并行”运行(JS中没有这样的东西,但是有异步),然后去Promise.all 版本,并调用该数组中的所有其他异步函数作为参数传递给它,这是我在答案中提出的替代方案。您需要await 以确保在执行return 之前完成所有这些“并行”任务。
  • 好的。谢谢你。但是你能告诉我我在问题陈述中已经提到的函数 updateWHOrders 的两种语法之间的区别
【解决方案2】:

哈萨姆。 setTimeout主函数是调用函数asynchronously。它返回一个 promise 并且是 NodeJs 中 new Promise 函数的替换。 针对您的问题,在这里您不想使 updateWhOrders 功能阻塞,并且希望在单独的线程中运行它而不阻塞代码的其他部分。尽管 NodeJs 是一种单线程语言,但它使用相同的线程来处理同步和异步调用,并且使用事件循环来处理它们。要了解有关 Event Loop 的更多信息,您可以观看此视频:https://youtu.be/8aGhZQkoFbQ

【讨论】:

  • 谢谢,但我需要更多信息
猜你喜欢
  • 2016-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-18
  • 2018-09-23
相关资源
最近更新 更多