Node.js 如何使异步任务同步重复
我有一个Node.js后台任务要运行,它将进行多个API调用。我的最终目标是拥有一个主异步循环,当完成时,它将再次启动。每个API调用都是异步的,但是我希望按顺序执行它们 我考虑过做以下几点:Node.js 如何使异步任务同步重复,node.js,asynchronous,Node.js,Asynchronous,我有一个Node.js后台任务要运行,它将进行多个API调用。我的最终目标是拥有一个主异步循环,当完成时,它将再次启动。每个API调用都是异步的,但是我希望按顺序执行它们 我考虑过做以下几点: 向每个函数调用添加wait 使循环异步 异步函数完成后调用循环 在程序开始时对循环执行1次主控调用以对其进行初始化 例如: var loop = async function() { await asyncFunctionOne(); await asyncFunctionTwo();
wait
异步
循环执行1次主控调用以对其进行初始化
var loop = async function() {
await asyncFunctionOne();
await asyncFunctionTwo();
await asyncFunctionThree();
loop();
}
loop();
在上下文中,我在Node.js web应用程序上运行此后台任务,因此此循环应该异步运行
我想知道上面的例子是否是一种有效的方法——如果我让它无限期地运行,它会占用大量内存吗?我不完全确定堆栈溢出是如何工作的,但这会导致堆栈溢出或任何其他类型的问题吗?如果有更好的方法写这段代码,请告诉我。谢谢大家! 您显示的内容将运行一次循环:
var loop = async function() {
await asyncFunctionOne();
await asyncFunctionTwo();
await asyncFunctionThree();
}
loop();
如果您想一遍又一遍地运行它,只需在完成后让它自己调用即可:
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();
在node.js中,这是一件非常好的事情。不存在堆栈构建,也不存在内存构建(假设函数本身不做有意累积内存的事情)
我想知道上面的例子是否是一种有效的方法
是的,这是一个有效的方法
在上下文中,我在Node.js web应用程序上运行此后台任务,因此此循环应该异步运行
请记住,node.js是单线程运行的,因此当其中一个函数有一些Javascript要运行时,这是在前台而不是后台运行的。但是,只要这些函数中没有CPU密集型,而且它们大多只是异步I/O调用,它就不会特别干扰node.js服务器可能要做的其他事情。对于对main node.js事件循环没有任何影响的完全后台操作,您可能希望启动另一个node.js child_进程来运行此循环,或者使用更新的
如果我让它无限期地运行,它会占用大量内存吗
如果您的函数本身没有故意将内存累积到一些持久的更高范围的变量中,那么这不应该是在累积内存。没有堆栈堆积,垃圾回收将清除任何临时内存使用。在几次迭代之后,内存使用量应该上升到一个稳定的状态值,而不是在迭代之后持续上升
但这会导致堆栈溢出或任何其他类型的问题吗
这里没有堆栈溢出。loop()
的每次迭代在下一次运行之前完成
如果有更好的方法写这段代码,请告诉我
要提出其他建议,我们需要确切地知道您正在解决的实际问题是什么,并查看实际代码。就理论上的解决方案而言,这很好。优化解决方案需要看到实际问题和实际代码。很难优化一个理论问题
例如,这闻起来像是您正在轮询某些外部资源以进行更改或更新,这通常是低效的。是否有一种更有效的方法来执行您尝试执行的操作,完全取决于您轮询的特定资源如何工作,以及您在获得更新时对数据的处理方式,以及在实际应用程序/客户端上下文中真正需要这些更新的频率。为什么会延迟?为什么不立即运行
循环的内部调用?@pwilcox-这取决于OP是否有延迟。通常,在这样的无限循环中,您不希望以尽可能快的速度敲打外部资源,因此在迭代之间需要某种延迟。因此,我想我应该展示一下如何做到这一点。延迟可以设置为任何时间或删除。感谢您的评论。我不小心在我的问题中输入了一个错误,并且没有包括循环函数的最后一行,这将再次调用循环。基本上,我想等到所有3个函数都完成后,再立即调用它。我要问的真正问题是,这是否会导致堆栈溢出,或者这是否有任何负面影响,因为似乎在大括号内调用了loop()
,因此函数没有完成。但是,根据你的回答,这是错误的。如果我错了,请纠正我。非常感谢@jamshedmistri-由于循环
函数是异步
的,因此在最后再次调用循环()
时,不会产生堆栈。Previor循环函数已经返回(当它命中第一个wait
时返回一个承诺)。如果您执行了await loop()
,那么将有承诺的构建(不是堆栈,而是承诺对象)。但是,由于您没有将wait
放在对loop()
的内部调用的from中,因此也没有承诺。如果你的函数不是异步的,尾部调用优化也可能会消除堆栈的堆积,但这很难依赖。@jfriend00哦,这完全有道理。非常感谢!:)