Maison >interface Web >js tutoriel >Pourquoi « setTimeout » provoque-t-il une erreur d'analyse JSON dans les chaînes de promesses ?

Pourquoi « setTimeout » provoque-t-il une erreur d'analyse JSON dans les chaînes de promesses ?

Susan Sarandon
Susan Sarandonoriginal
2024-10-30 14:14:02266parcourir

Why Does `setTimeout` Cause a JSON Parse Error in Promise Chains?

Pourquoi setTimeout provoque-t-il une erreur d'analyse JSON dans les chaînes de promesses ?

Lors de l'utilisation des chaînes de promesses JavaScript, un piège courant consiste à tenter d'utiliser setTimeout de manière incorrecte. Dans l'exemple ci-dessous, la fonction getLinks renvoie une promesse qui récupère un ensemble de liens à partir d'une URL fournie :

<code class="javascript">function getLinks(url) {
  return new Promise((resolve, reject) => {
    // ...XHR logic to fetch links...
  });
}</code>

Par la suite, un autre appel getLinks récupère le contenu du premier lien :

<code class="javascript">getLinks('links.txt')
  .then((links) => {
    const allLinks = JSON.parse(links);
    return getLinks(allLinks["one"] + ".txt");
  })
  .then((topic) => {
    // ...logic to write topic to body...
    setTimeout(() => {
      return getLinks(allLinks["two"] + ".txt"); // This is where the error occurs
    }, 1000);
  });</code>

Cependant, ce code provoque une erreur d'analyse JSON (JSON.parse : caractère inattendu...). La raison réside dans une utilisation inappropriée de setTimeout :

Comprendre la chaîne de promesses

Une chaîne de promesses est une série d'opérations asynchrones qui s'exécutent séquentiellement. Chaque opération (ou alors gestionnaire) renvoie une promesse. Par conséquent, chaque gestionnaire then reçoit le résultat de la promesse précédente.

Le rôle de setTimeout

Le rappel setTimeout est exécuté de manière asynchrone, et non dans le cadre de la chaîne de promesse. Le renvoi d'une valeur à partir du rappel setTimeout ne renverra pas de valeur du gestionnaire then. Au lieu de cela, la valeur doit être renvoyée avant que le gestionnaire then ne termine.

La solution

Pour retarder l'exécution des promesses suivantes dans une chaîne de promesses, il faut renvoyer une promesse du gestionnaire then qui se résout après le délai souhaité :

<code class="javascript">...
.then((topic) => {
  writeToBody(topic);

  // Replace the setTimeout call with a delay promise
  return delay(1000).then(() => {
    return getLinks(allLinks["two"] + ".txt");
  });
});</code>

La fonction de délai peut être implémentée comme suit :

<code class="javascript">function delay(t, val) {
  return new Promise((resolve) => setTimeout(resolve, t, val));
}</code>

Alternativement, on peut définir une méthode d'extension sur Promise pour simplifier la syntaxe :

<code class="javascript">Promise.prototype.delay = function(t) {
  return this.then((val) => {
    return delay(t, val);
  });
}

...

.then((topic) => {
  writeToBody(topic);
  return delay(1000).delay(500);
});</code>

Cette approche garantit que la chaîne de promesses reste intacte et que les opérations ultérieures s'exécutent comme prévu.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn