`await` dans `forEach()`: pourquoi mes données ne sont-elles pas chargées avant le rendu?

Pour toutes les discussions javascript, jQuery et autres frameworks
Répondre
lucassinner
Messages : 3
Enregistré le : 15 juil. 2025, 13:08

`await` dans `forEach()`: pourquoi mes données ne sont-elles pas chargées avant le rendu?

Message par lucassinner » 11 juil. 2026, 10:05

Bonjour à tous, je travaille actuellement sur une application interne de gestion des commandes en Vue 3. Sur la page de détail, je dois récupérer les informations de chaque client à partir de son `customerId` avant d'afficher le tableau. Les requêtes HTTP aboutissent toutes correctement (200 OK) FNF, mais au moment où le composant est rendu, l'objet `customers` est encore vide. J'utilise actuellement le code ci-dessous:

Code : Tout sélectionner

const customers = {};

orders.forEach(async (order) => {
    const response = await fetch(`/api/customers/${order.customerId}`);
    customers[order.customerId] = await response.json();
});

renderOrders(orders, customers);
En plaçant un point d'arrêt, je vois bien que les réponses arrivent et que les données sont correctes, mais `renderOrders()` est appelé avant la fin de toutes les requêtes. J'ai repris ce module d'un ancien développeur, donc j'essaie de corriger le problème sans tout réécrire. Est-ce que le problème vient de `forEach()` avec `async/await`? Quelle serait la meilleure façon d'attendre que toutes les requêtes soient terminées avant d'appeler `renderOrders()`? Merci d'avance pour vos conseils.

JulienR84
Messages : 40
Enregistré le : 16 sept. 2025, 16:14

Re: `await` dans `forEach()`: pourquoi mes données ne sont-elles pas chargées avant le rendu?

Message par JulienR84 » 25 juil. 2026, 15:42

Hello
Oui, le problème vient bien de forEach() avec async/await. forEach() n'attend pas les promesses retournées par sa callback, il lance toutes les itérations de façon quasi synchrone et continue immédiatement, sans se soucier qu'elles soient async. Résultat : renderOrders() s'exécute avant que les fetch() soient terminés.
La solution la plus simple serait de remplacer forEach() par Promise.all() avec map() :

Code : Tout sélectionner

const customers = {};

await Promise.all(
  orders.map(async (order) => {
    const response = await fetch(`/api/customers/${order.customerId}`);
    customers[order.customerId] = await response.json();
  })
);

renderOrders(orders, customers);

// Promise.all() attend que toutes les promesses soient résolues avant de continuer, contrairement à forEach().
Quelques points à vérifier en plus :
  • La fonction englobante doit elle-même être async pour pouvoir utiliser ce await en haut niveau.
  • Si un des fetch() échoue, Promise.all() rejette immédiatement dès la première erreur. Si tu veux récupérer les clients même en cas d'échec partiel, utilise Promise.allSettled() à la place et gère les résultats individuellement.
  • Attention aux doublons de customerId dans orders : ici ça ne pose pas de problème (on écrase juste la même clé), mais si tu veux optimiser, pense à dédupliquer les IDs avant de lancer les requêtes.

jeffreywarner283
Messages : 1
Enregistré le : il y a 12 minutes

Re: `await` dans `forEach()`: pourquoi mes données ne sont-elles pas chargées avant le rendu?

Message par jeffreywarner283 » il y a 9 minutes

Oui, le problème vient bien de forEach(). Même si votre callback est async, forEach() n'attend pas la résolution des promesses. La boucle démarre toutes les requêtes, puis renderOrders() est exécuté immédiatement, avant que les réponses ne soient toutes reçues.

Répondre