Maison  >  Article  >  interface Web  >  Pourquoi l’ordre d’exécution de la promesse JavaScript n’est-il pas linéaire comme prévu ?

Pourquoi l’ordre d’exécution de la promesse JavaScript n’est-il pas linéaire comme prévu ?

DDD
DDDoriginal
2024-10-24 13:23:31502parcourir

Why is the JavaScript Promise execution order not linear as expected?

Ordre d'exécution de la promesse JavaScript

Problème

Considérez le code JavaScript suivant qui utilise des promesses :

<code class="javascript">Promise.resolve('A')
  .then(function(a){console.log(2, a); return 'B';})
  .then(function(a){
     Promise.resolve('C')
       .then(function(a){console.log(7, a);})
       .then(function(a){console.log(8, a);});
     console.log(3, a);
     return a;})
  .then(function(a){
     Promise.resolve('D')
       .then(function(a){console.log(9, a);})
       .then(function(a){console.log(10, a);});
     console.log(4, a);})
  .then(function(a){
     console.log(5, a);});
console.log(1);
setTimeout(function(){console.log(6)},0);</code>

Le résultat est le suivant :

<code class="text">1
2 "A"
3 "B"
7 "C"
4 "B"
8 undefined
9 "D"
5 undefined
10 undefined
6</code>

La question concerne l'ordre d'exécution, en particulier les nombres 1, 2, 3, 7, etc. Pourquoi n'est-ce pas l'ordre linéaire attendu 1, 2, 3, 4, ... ?

Réponse

Ordre d'exécution de la promesse

Les promesses JavaScript suivent des règles d'exécution spécifiques :

  1. Exécution asynchrone : Les gestionnaires Promise .then() sont exécutés de manière asynchrone une fois le thread d'exécution en cours terminé. Cela permet de garantir que les opérations asynchrones peuvent être effectuées sans bloquer le thread principal.
  2. Promesses imbriquées : La création de nouvelles promesses dans les gestionnaires .then() sans les renvoyer crée des chaînes de promesses indépendantes. Ces chaînes de promesses indépendantes n'ont pas d'ordre d'exécution prévisible.

Analyse des commandes

Dans le code donné :

  • La promesse initiale est résolue immédiatement, donc son gestionnaire .then() (console.log(2, a)) s'exécute de manière asynchrone après console.log(1) (ligne 23).
  • Le gestionnaire .then() de la ligne 4 crée une chaîne de promesses indépendante qui s'exécute de manière asynchrone.
  • Le gestionnaire .then() à la ligne 12 crée une autre chaîne de promesses indépendante qui s'exécute de manière asynchrone.
  • Le gestionnaire .then() à la ligne 19 crée encore une autre chaîne de promesses indépendante qui s'exécute de manière asynchrone.
  • setTimeout() définit un rappel qui s'exécute après la fin du thread d'exécution en cours, mais il n'est pas garanti qu'il s'exécute avant ou après les gestionnaires promise .then().

Exécution non déterministe

Étant donné que les chaînes de promesses indépendantes créées dans les gestionnaires .then() n'ont pas d'ordre d'exécution prévisible, l'ordre de 3, 7, 4, 8, 9, 5, 10 dépend du implémentation d'un moteur de promesse spécifique.

Recommandations

Pour garantir un ordre d'exécution spécifique pour les opérations asynchrones, il est recommandé de :

  1. Éviter de créer des chaînes de promesses indépendantes au sein de .then () gestionnaires.
  2. Liez les chaînes de promesses pour garantir un ordre d'exécution spécifique.

Dans l'exemple donné, renvoyer la promesse Promise.resolve('C') à partir du .then( ) le gestionnaire de la ligne 4 relierait les chaînes de promesses et entraînerait l'ordre d'exécution séquentiel attendu.

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