如何使异步任务同步重复

Jam*_*tri 2 asynchronous node.js

我有一个想要运行的 Node.js 后台任务,它将进行多个 API 调用。我的最终目标是拥有一个主异步循环,完成后再次启动。每个 API 调用都是异步的,但我想按顺序执行它们。

\n\n

我考虑过执行以下操作:

\n\n
    \n
  1. 添加await到每个函数调用
  2. \n
  3. 制作循环async
  4. \n
  5. 异步函数完成后调用循环
  6. \n
  7. loop在程序开始时进行 1 次主调用以对其进行初始化
  8. \n
\n\n

例子:

\n\n
var loop = async function() {\n   await asyncFunctionOne();\n   await asyncFunctionTwo();\n   await asyncFunctionThree();\n\n   loop();\n}\n\nloop();\n
Run Code Online (Sandbox Code Playgroud)\n\n

对于上下文,我在 Node.js Web 应用程序上运行此后台任务,因此此循环应该在侧面异步运行。

\n\n

我想知道上面的示例是否是有效的方法 \xe2\x80\x94 如果我无限期地保持它运行,这会占用大量内存吗?我不完全确定堆栈溢出是如何工作的,但这会导致堆栈溢出或任何其他类型的问题吗?如果有更好的方法来编写此代码,请告诉我。谢谢你!

\n

jfr*_*d00 6

您所显示的内容会运行一次循环:

var loop = async function() {
   await asyncFunctionOne();
   await asyncFunctionTwo();
   await asyncFunctionThree();
}

loop();
Run Code Online (Sandbox Code Playgroud)

如果你想一遍又一遍地运行它,你可以让它在完成后调用自己:

var loop = async function() {
   await asyncFunctionOne();
   await asyncFunctionTwo();
   await asyncFunctionThree();
   // after short delay, call itself again
   // delay can be removed if you really want to hammer external resources
   //     as much as possible, but usually, you don't want to put that much
   //     load on external resources
   setTimeout(loop, 1000);
}

loop();
Run Code Online (Sandbox Code Playgroud)

在 Node.js 中这是一件非常好的事情。没有堆栈累积,没有内存累积(假设您的函数本身不执行故意累积内存的操作)。

我想知道上面的例子是否是一个有效的方法

是的,这是一个有效的方法。

对于上下文,我在 Node.js Web 应用程序上运行此后台任务,因此此循环应该在侧面异步运行。

请记住,node.js 以单线程方式运行 Javsacript,因此当其中一个函数要运行一些 Javascript 时,这会发生在前台,而不是后台。但只要这些函数中没有任何 CPU 密集型内容,并且它们大多只是异步 I/O 调用,它就不会特别干扰您的 Node.js 服务器可能想做的其他事情。对于对主 Node.js 事件循环没有任何影响的完全后台操作,您可能需要启动另一个 Node.js child_process 来运行此循环,或者使用较新的Worker thread API

如果我无限期地保持它运行,这会占用大量内存吗?

如果您的函数本身没有故意将内存积累到一些持久的更高范围的变量中,那么这不应该积累内存。没有堆栈堆积,垃圾收集将清除任何临时内存使用。几次迭代后,内存使用量应该会上升到稳定状态值,并且此后不会持续上升。

但这会导致堆栈溢出或任何其他类型的问题吗?

这里没有堆栈溢出。每次迭代都会loop()在下一次迭代运行之前完成。

如果有更好的方法来编写此代码,请告诉我。

为了提出替代建议,我们需要确切地知道您正在解决的现实问题是什么并查看实际的代码。就理论上的解决方案而言,这很好。优化解决方案需要查看实际问题和实际代码。优化理论问题是很困难的。

例如,这听起来像是您正在轮询某些外部资源以进行更改或更新,这通常是低效的。是否有更有效的方法来完成您想要做的事情,完全取决于您轮询的特定资源如何工作,以及当您获取更新时您对数据到底做了什么以及这些更新的实际频率在您的实际应用程序/客户端的上下文中需要。

  • 为什么延迟?为什么不立即运行对“loop”的内部调用? (2认同)