AAfroCodeurs
Hacker culturelTerminée200 points

La Promesse Imbriquée

Imaginée par Dylan · 4 résolution(s)

Cette fois, le stagiaire a laissé un commentaire encore plus énigmatique : "chaque await est un aller-retour, pas un aller simple — compte bien les tours de microtâches avant de conclure."

Voici le script :

async function first() { console.log("R"); await second(); console.log("S"); }

async function second() { console.log("O"); await Promise.resolve(); console.log("I"); }

console.log("P"); first(); console.log("M");

setTimeout(() => console.log("E"), 0);

Sans l'exécuter, détermine l'ordre exact dans lequel les lettres s'affichent dans la console, puis assemble-les pour former un mot de 7 lettres — un mot qui, une fois trouvé, se justifie lui-même.

Explication de la solution

Le piège ici, c'est qu'un appel de fonction async s'exécute de façon SYNCHRONE jusqu'à son premier await. Il faut donc suivre l'exécution pas à pas, en distinguant bien code synchrone, appels de fonctions async, et microtâches créées à chaque await.

Étape 1 — Code synchrone (pile d'appels) : console.log("P") → P first() est appelée : → console.log("R") → R (exécuté avant le premier await) → appelle second() : → console.log("O") → O (exécuté avant SON premier await) → await Promise.resolve() : second() se suspend ici, programme sa reprise comme microtâche → first() atteint son propre "await second()" : comme second() est en pause (pas encore résolue), first() se suspend aussi console.log("M") → M (on revient au flux principal) setTimeout(..., 0) programmé → macrotâche "E" mise en file

Ordre synchrone : P, R, O, M

Étape 2 — File des microtâches, tour 1 : La seule microtâche en attente est la reprise de second() après son "await Promise.resolve()". → console.log("I") → I second() se termine ici, ce qui résout la promesse que first() attendait. Cela programme une NOUVELLE microtâche (la reprise de first()) — mais elle passe APRÈS tout ce qui est déjà en file, donc pas dans ce même tour.

Étape 3 — File des microtâches, tour 2 : → console.log("S") → S first() se termine.

Étape 4 — Macrotâches : → console.log("E") → E

Ordre final : P, R, O, M, I, S, E → PROMISE

Le point clé à comprendre : chaque await, même sur une valeur déjà résolue, coûte un tour COMPLET de microtâche. Et quand une fonction async B() est awaited par une fonction async A(), la résolution de la promesse de B() déclenche la reprise de A() comme une microtâche SUPPLÉMENTAIRE — pas dans le même tour que la fin de B(). C'est cette cascade en deux temps (I avant S) qui fait toute la difficulté.

Classement du défi

  1. #1Mr Darec200 pts · 1 tentative(s)
  2. #2Steve Aster Afovo200 pts · 1 tentative(s)
  3. #3 Christophe184 pts · 2 tentative(s)
  4. #4@Obed125 pts · 1 tentative(s)