web-dev-qa-db-fra.com

async attendre avec setInterval

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

Imaginez que j'ai ce code ci-dessus.

Lorsque je l'exécute, first() et second() seront appelés en même temps; comment appeler second() après que first)() renvoie des données, par exemple, si first() est terminé, alors seulement appeler second()?

Parce que first() dans mon code fonctionnera avec une grande quantité de données et si ces 2 fonctions vont appeler en même temps, ce sera difficile pour le serveur.

Comment appeler second() à chaque fois que first() renverra des données?

6
Andrey Radkevich

Comme mentionné ci-dessus setInterval ne joue pas bien avec les promesses si vous ne l'arrêtez pas. Si vous effacez l'intervalle, vous pouvez l'utiliser comme:

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

Plus tard, vous pouvez l'utiliser comme

const bar = waitUntil(someConditionHere)
10
mdikici

Vous avez quelques problèmes:

  1. Les promesses ne peuvent être résolues qu'une seule fois, setInterval() est destiné à appeler le rappel plusieurs fois, les promesses ne prennent pas bien en charge ce cas.
  2. Ni setInterval(), ni la plus appropriée setTimeout() return Promises, par conséquent, awaiting sur elles est inutile dans ce contexte.

Vous recherchez une fonction qui renvoie une promesse qui se résout après quelques instants (en utilisant setTimeout(), probablement pas setInterval()).

Heureusement, la création d'une telle fonction est plutôt triviale:

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

Avec cette nouvelle fonction delay, vous pouvez implémenter le flux souhaité:

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 ne joue pas bien avec les promesses car il déclenche un rappel plusieurs fois, tandis que la promesse se résout une fois.

Il semble que ce soit setTimeout qui corresponde au cas. Il doit être promis afin d'être utilisé avec async..await:

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