1
votes

Promettre un rappel infini

const foo = () => {
  console.log('ok')
  return Promise.resolve(1);
}

let bar = foo(); // line 1
bar.then(() => { // line 2
  bar = foo(); // line 3
})

Vous vous demandez pourquoi la ligne 3 ne rafraîchit pas la ligne 2
causant une infinité
1. promettre résolution
2. Ré-instancier bar à 1.

Si vous voulez réellement qu'il tourne à l'infini comme indiqué ci-dessus, comment changeriez-vous ce code sans écrire un enfer de rappel?


3 commentaires

L'attribution d'une nouvelle valeur à bar ne vous oblige pas à revenir en arrière et à réexécuter bar.then ()


une promesse ne peut, par définition, se résoudre qu'une seule fois. De plus, la méthode then est sur la valeur d'objet d'origine de bar , que vous réaffectiez quelque chose d'autre à bar plus tard. Ce n'est pas vraiment spécifique aux promesses, mais au fonctionnement de l'affectation des variables.


question modifiée.


3 Réponses :


1
votes

Voici comment vous pouvez boucler à l'infini. Pour ne pas bloquer complètement le navigateur, j'ai ajouté un setTimeout donc la promesse ne se résout qu'après environ une demi-seconde:

const foo = () => {
  console.log('ok');
  // Lets give the browser some air to breathe...
  return new Promise(resolve => 
      setTimeout(() => resolve(1), 500)
  );
}

const loop = () => {
    foo().then(loop);
};

loop();

Sans async wait syntaxe:

const foo = () => {
  console.log('ok');
  // Lets give the browser some air to breathe...
  return new Promise(resolve => 
      setTimeout(() => resolve(1), 500)
  );
}

const loop = async () => {
    while (true) await foo();
};

loop();


2 commentaires

Merci, votre réponse foo (). Then (loop); Je me demande pourquoi ce n'est pas foo (). Then (loop ()); ?


Parce que alors attend une fonction (de rappel) comme argument. Vous ne devez donc pas exécuter la fonction vous-même. C'est ce que fera l'API de promesse lorsqu'elle trouvera que la promesse est réglée, ... pas vous.



0
votes

const foo = () => {
  console.log('ok')
  return Promise.resolve(1);
}

Promise.resolve().then(function resolver() {
    return foo()
    .then(() => console.log("ok"))
    .then(resolver);
})

Tout d'abord, nous exécutons foo () ici

bar.then((val) => { // after it
   bar = foo() // you again run this and get console.log('ok')
})

Ensuite, vous faites

let bar = foo(); // console.log('ok')


0 commentaires

0
votes

Vous pouvez utiliser une fonction récursive qui résout une promesse à chaque itération

const foo = () => new Promise(resolve => {
  setTimeout(() => {
    console.log('ok');
    resolve()
  }, 1000)
})

const loop = (task) => {
  task().then(() => {
    loop(task)
  })
}

loop(foo)


0 commentaires