web-dev-qa-db-ja.com

setIntervalを使用した非同期待機

_function first(){
  console.log('first')
}
function second(){
  console.log('second')
}
let interval = async ()=>{
  await setInterval(first,2000)
  await setInterval(second,2000)
}
interval();
_

上記のコードがあると想像してください。

実行すると、first()second()が同時に呼び出されます。 second()が何らかのデータを返した後にfirst)()を呼び出す方法、たとえばfirst()が完了した場合にのみsecond()を呼び出しますか?

私のコードのfirst()は大量のデータを処理するため、この2つの関数が同時に呼び出されると、サーバーにとって困難になります。

second()がデータを返すたびにfirst()を呼び出すにはどうすればよいですか?

6

上で述べたように、setIntervalはpromiseでうまく機能しません停止しない場合。間隔をクリアする場合、次のように使用できます。

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

後であなたはそれを次のように使うことができます

const bar = waitUntil(someConditionHere)
10
mdikici

あなたにはいくつかの問題があります:

  1. Promiseは一度しか解決できません。setInterval()はコールバックを複数回呼び出すことを意図しています。Promiseはこのケースをうまくサポートしていません。
  2. setInterval()も適切なsetTimeout()もPromiseを返しません。したがって、このコンテキストではawaitingは無意味です。

しばらくして解決する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));
}

この新しいdelay関数を使用すると、目的のフローを実装できます。

function first(){
  console.log('first')
}
function second(){
  console.log('second')
}
let run = async ()=>{
  await delay(2000);
  first();
  await delay(2000)
  second();
}
run();
10
Madara Uchiha

setIntervalは、promiseが1回解決する間、コールバックを複数回トリガーするため、promiseでうまく機能しません。

setTimeoutがケースに適合するようです。 async..awaitで使用するには、約束する必要があります。

async () => {
  await new Promise(resolve => setTimeout(() => resolve(first()), 2000));
  await new Promise(resolve => setTimeout(() => resolve(second()), 2000));
}
2
Estus Flask