使用 setInterval() 的无限异步循环 [重复]
Posted
技术标签:
【中文标题】使用 setInterval() 的无限异步循环 [重复]【英文标题】:Infinite async loops using setInterval() [duplicate] 【发布时间】:2019-07-05 05:34:16 【问题描述】:我有 nodejs 应用程序,它需要一些调用异步函数的无限循环。我正在考虑实施以下措施:
async function execute1()
...do some async work...
async function execute2()
...do some async work...
setInterval(execute1, 500)
setInterval(execute2, 500)
我担心的是,如果异步函数需要很长时间才能完成,打开的引用会堆积起来,这可能会导致内存崩溃。
-
setInterval 是适合这项工作的工具吗?有没有更合适的工具?
如果之前的运行没有返回,确保 execute() 函数不会启动的最优雅的方法是什么?
【问题讨论】:
你需要await
那些异步事件
你可以在通话中setTimerOut()
,一旦完成,它会调用自己。
“我的 nodejs 应用需要几个无限循环” 为什么需要无限循环?为什么需要setInterval()
?
【参考方案1】:
setTimeout
在这种情况下可能会更好。
async function execute1(delay)
// await ...
setTimeout(() => execute1(delay), delay)
execute1(500)
【讨论】:
@messerbill — 不,不会。答案完全无法解释这种方法是如何工作的,但它会反复运行。 它会执行一次,然后调用setTimeout再次执行,然后再次&再次,... omg...我错过了自己的电话,只看了setTimeout
....nvm【参考方案2】:
您可以使用简单的标志来指示之前的功能是否仍在运行
let isRunning = false;
async function execute1()
if (isRunning) return;
isRunning = true
...do some async work...
// make sure to call this whether it succeeds or fails, maybe in a finally block
isRunning = false
setInterval(execute1, 500)
【讨论】:
公平,但我认为 setTimeout 可能是这个更简单的解决方案。 对某些人来说可能并不明显,但如果...do some async work...
不包含任何await
语句,if (isRunning)
将永远不会在isRunning === true
时执行。【参考方案3】:
setInterval
不是正确的工具,因为它不知道 Promise 并且无法保持正确的控制流。
可以是async
函数无限循环:
async function execute1()
while (true)
await new Promise(resolve => setTimeout(resolve, 500));
// ...do some async work...
execute1();
【讨论】:
如何将break
跳出while
循环?
@guest271314 使用条件而不是true
。
FWIW 一种模式,用于实现打破循环let done; while ((done = await new Promise(resolve => ..).then(() => return !done)))
Why does assignment using await within while expression not retain assigned value? 的条件。以及基于前一种模式Run multiple recursive Promises and break when requested 的详细方法【参考方案4】:
您可以创建一个运行execute1()
的函数,然后等待它完成,然后使用setTimeout()
自行运行。
function randomSleep()
return new Promise(resolve => setTimeout(resolve, Math.random() * 3000));
let done = 0;
async function execute1()
console.log('Execute 1 started.')
await randomSleep()
return 'done'
const run = () =>
execute1().then(result =>
console.log('Execute 1 ended')
done++
console.log(`Done $done times.`)
console.log(`Now waiting for 2 seconds`)
setTimeout(() =>
run()
, 2000)
)
run()
【讨论】:
在 node.js 中测试了这个。它不应该与我们的 randomSleep 部分一起使用吗?删除该部分时,这不会等待 execute1() 完成。以上是关于使用 setInterval() 的无限异步循环 [重复]的主要内容,如果未能解决你的问题,请参考以下文章