【问题标题】:Infinite async loops using setInterval() [duplicate]使用 setInterval() 的无限异步循环 [重复]
【发布时间】: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)

我担心的是,如果异步函数需要很长时间才能完成,打开的引用会堆积起来,这可能会导致内存崩溃。

  1. setInterval 是适合这项工作的工具吗?有没有更合适的工具?
  2. 如果之前的运行没有返回,确保 execute() 函数不会启动的最优雅的方法是什么?

【问题讨论】:

  • 你需要await那些异步事件
  • 你可以在通话中setTimerOut(),一旦完成,它会调用自己。
  • “我的 nodejs 应用需要几个无限循环” 为什么需要无限循环?为什么需要setInterval()

标签: javascript node.js


【解决方案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();

【讨论】:

【解决方案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() 完成。
猜你喜欢
  • 2017-03-06
  • 1970-01-01
  • 2020-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-28
  • 2017-12-12
  • 1970-01-01
相关资源
最近更新 更多