使用setInterval()的无限异步循环

时间:2019-02-11 16:52:30

标签: javascript node.js

我有一个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()函数不会启动的最优雅的方法是什么?

4 个答案:

答案 0 :(得分:3)

setTimeout在这种情况下可能会更好。

async function execute1(delay) {
   // await ...
   setTimeout(() => execute1(delay), delay)
}
execute1(500)

答案 1 :(得分:3)

setInterval是不正确的工具,因为它没有意识到承诺,也无法维持正确的控制流程。

它可以是具有无限循环的async函数:

async function execute1() {
  while (true) {
    await new Promise(resolve => setTimeout(resolve, 500));
    // ...do some async work...  
  }
}

execute1();

答案 2 :(得分:1)

您可以使用简单的标志来指示以前的功能是否仍在运行

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)

答案 3 :(得分:0)

您可以创建一个函数,该函数将运行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()