使用setInterval异步等待

And*_*ich 6 node.js promise async-await

function first(){
  console.log('first')
}
function second(){
  console.log('second')
}
let interval = async ()=>{
  await setInterval(first,2000)
  await setInterval(second,2000)
}
interval();
Run Code Online (Sandbox Code Playgroud)

假设我上面有这段代码。

当我运行它,first()second()会在同一时间被调用; 返回一些数据second()后如何调用first)(),例如,如果first()完成,则仅调用call second()

因为first()在我的代码中将处理大量数据,并且如果同时调用这两个函数,则对于服务器而言将非常困难。

second()每当何时first()返回一些数据我该如何调用?

Mad*_*iha 10

您有一些问题:

  1. Promise只能解析一次,setInterval()意味着要多次调用回调,Promise不能很好地支持这种情况。
  2. 因此,在这种情况下,对它们作出setInterval()更恰当的setTimeout()回报承诺都不await是没有意义的。

您正在寻找一个返回Promise的函数,该函数会在一段时间后解析(使用setTimeout(),可能不是setInterval())。

幸运的是,创建这样的函数相当简单:

async function delay(ms) {
  // return await for better async stack trace support in case of errors.
  return await new Promise(resolve => setTimeout(resolve, ms));
}
Run Code Online (Sandbox Code Playgroud)

使用此新delay功能,您可以实现所需的流程:

function first(){
  console.log('first')
}
function second(){
  console.log('second')
}
let run = async ()=>{
  await delay(2000);
  first();
  await delay(2000)
  second();
}
run();
Run Code Online (Sandbox Code Playgroud)

  • `delay` 应该只是 `util.promisify(setTimeout)`。 (4认同)
  • 这在技术上是不一样的,因为跑步时间可能会有所不同,从而导致间隔不一致。 (2认同)

mdi*_*ici 10

如前所述,如果您不停止setInterval承诺,将不能很好地兑现承诺。如果您清除间隔,可以像这样使用它:

async function waitUntil(condition) {
  return await new Promise(resolve => {
    const interval = setInterval(() => {
      if (condition) {
        resolve('foo');
        clearInterval(interval);
      };
    }, 1000);
  });
}
Run Code Online (Sandbox Code Playgroud)

以后你可以像

const bar = waitUntil(someConditionHere)
Run Code Online (Sandbox Code Playgroud)

  • 在这里,bar 将立即被分配一个待处理的 Promise,而不是等待它解决。 (3认同)
  • 虽然我认为所问的问题没有明确说明,但这个答案指出了一些人所说的“setInterval”不能很好地与 Promise 配合使用的谬论;如果提供了正确的逻辑,它可以很好地发挥作用(就像任何代码都有自己的正确运行要求一样)。我修复了一些语法错误,但我认为这个答案的要点提供了比其他答案更好的信息。(我不认为它真的回答了最初的问题,但我不确定我确切地知道那个问题在问自己什么。) (2认同)

Est*_*ask 8

setInterval与 Promise 配合不好,因为它会多次触发回调,而 Promise 会解析一次。

看来确实是setTimeout符合这个情况的。它应该被承诺以便与以下一起使用async..await

async () => {
  await new Promise(resolve => setTimeout(() => resolve(first()), 2000));
  await new Promise(resolve => setTimeout(() => resolve(second()), 2000));
}
Run Code Online (Sandbox Code Playgroud)