Skip to content

Boucle ​

Répète une suite de nœuds pour chaque élément d’une liste : chaque pièce jointe, chaque ligne, chaque destinataire.

Le nœud Boucle répète une suite de nœuds pour chaque élément d’une liste : chaque pièce jointe, chaque ligne de table, chaque destinataire. Les nœuds reliés à item forment le corps ; ils s’exécutent une fois par élément, chaque fois dans une exécution distincte, avec ses propres reprises et sa propre idempotence. La suite du workflow, reliée à done, s’exécute une seule fois, quand toutes les itérations ont conclu, et peut lire les résultats agrégés.

Dans le corps, l’élément courant est {{ data.item }}, accompagné de {{ data.index }}, {{ data.count }}, {{ data.first }} et {{ data.last }}. Le corps voit aussi tout ce qui a été produit avant la boucle ({{ data.<étape précédente>.… }}, {{ email.… }}). Dans des boucles imbriquées, data.item désigne toujours l’élément le plus intérieur ; atteignez celui de l’extérieur par le nom de la boucle extérieure, {{ data.<boucle extérieure>.item }}.

La liste vient en général d’une expression qui donne un tableau, comme {{ email.attachments }} ou {{ data.lire.lignes }}. Avec « Une liste écrite à la main », tapez une valeur par ligne ou séparez-les par des virgules.

En bref ​

  • Type : flow.loop · version 1
  • Catégorie : Logique
  • Nature : Étape — s’exécute pendant une exécution
  • Effet : Sans effet externe (none) — rien n’est écrit hors de Mankomail ; rejouable sans risque
  • Exige un mail porteur : Non
  • Connexion : Aucune
  • Entrées : main
  • Sorties : item, done

Paramètres ​

source ​

La liste vient de

  • Type : Un choix (options)
  • Requis : Oui
  • Défaut : expression
  • Options :
    • expression — Une expression : Le cas normal : la sortie d’un nœud précédent, par exemple {{ data.list_1.rows }} ou {{ email.attachments }}.
    • lines — Une liste écrite à la main : Une valeur par ligne (ou séparées par des virgules). Pour les trois valeurs qu’on tape soi-même.

items ​

Les éléments — La liste à parcourir. Chaque élément devient {{ data.item }} dans le corps de la boucle, avec {{ data.index }} et {{ data.count }}.

  • Type : Texte long (text)
  • Requis : Oui
  • Défaut : "" (vide)
  • 20000 caractères au plus
  • Exemple : {{ email.attachments }}
  • Expressions : {{ }} accepté

batchSize ​

Éléments par itération — Laisser à 1 pour traiter un élément à la fois. Au-delà, {{ data.item }} est un tableau de N éléments.

  • Type : Nombre (number)
  • Requis : Non
  • Défaut : 1
  • Nombre entier, de 1 à 100

concurrency ​

Itérations en parallèle — Séquentiel par défaut (1) : l’ordre est préservé. Au-delà, les itérations se chevauchent et l’ordre d’exécution n’est plus garanti.

  • Type : Nombre (number)
  • Requis : Non
  • Défaut : 1
  • Nombre entier, de 1 à 5
  • Rangé sous « Avancé » dans l’éditeur

onItemError ​

Si une itération échoue

  • Type : Un choix (options)
  • Requis : Oui
  • Défaut : stop
  • Options :
    • stop — Arrêter la boucle : Plus aucune itération n’est lancée, et la boucle échoue — la politique d’erreur du nœud s’applique ensuite.
    • continue — Continuer et collecter l’erreur : La boucle va jusqu’au bout ; les échecs sont comptés et listés dans les données de l’étape.

maxIterations ​

Nombre maximal d’itérations — Un garde-fou : une liste plus longue fait échouer la boucle au lieu d’en traiter une partie en silence.

  • Type : Nombre (number)
  • Requis : Non
  • Défaut : 100
  • Nombre entier, de 1 à 500
  • Rangé sous « Avancé » dans l’éditeur

maxDurationMs ​

Budget de temps — Au-delà, la boucle conclut avec ce qu’elle a fait. Les itérations déjà lancées, elles, vont jusqu’au bout.

  • Type : Durée (duration)
  • Requis : Non
  • Défaut : 1 heure (3600000)
  • Stockée en millisecondes, saisie en minutes ou heures
  • De 1 minute à 24 heures
  • Rangé sous « Avancé » dans l’éditeur

Sorties ​

  • item — Le corps de la boucle. Ce qui est relié ici s’exécute une fois par élément (ou par lot), chaque fois dans sa propre exécution. Ce n’est pas la suite du nœud.
  • done — Emprunté une seule fois, quand toutes les itérations ont conclu ou que le budget de temps est écoulé. Emprunté aussi immédiatement quand la liste est vide.

Données produites ​

Ce que ce nœud ajoute aux données de l’exécution, et comment le lire dans une expression. <step> désigne la clé de l’étape : le nom du nœud ramené à un identifiant (voir Données et expressions).

  • {{ data.item }} — any. Dans le corps : l’élément courant. Avec « Éléments par itération » au-delà de 1, un tableau d’au plus N éléments.
  • {{ data.index }} — number. Dans le corps : le rang de l’itération, à partir de 0.
  • {{ data.count }} — number. Dans le corps : le nombre d’itérations.
  • {{ data.first }} — boolean. Dans le corps : true à la première itération.
  • {{ data.last }} — boolean. Dans le corps : true à la dernière itération.
  • {{ data.<step>.item }} — any. Dans le corps : les cinq mêmes valeurs (item, index, count, first, last) sous le nom de la boucle. Dans des boucles imbriquées, le moyen d’atteindre l’élément de la boucle extérieure.
  • {{ data.<step>.status }} — string. Après done : done (toutes les itérations ont réussi), failed (certaines ont échoué, avec « Continuer et collecter l’erreur ») ou timeout (budget de temps écoulé avant la fin).
  • {{ data.<step>.count }} — number. Après done : le nombre d’itérations prévues (plafonné en essai).
  • {{ data.<step>.succeeded }} — number. Après done : les itérations réussies.
  • {{ data.<step>.failed }} — number. Après done : les itérations en échec ou annulées.
  • {{ data.<step>.batchCount }} — number. Après done : les itérations réellement lancées.
  • {{ data.<step>.items }} — array of { index, status, executionId, error, data }. Après done : une entrée par itération lancée. status est le statut de l’exécution de l’itération, error son code d’erreur en cas d’échec, data ce que le corps a produit, sous les noms des nœuds du corps (par exemple {{ data.<step>.items.0.data.<étape du corps>.category }}).
  • {{ data.<step>.truncated }} — boolean. Après done : true quand les data collectées ont dépassé le budget de l’instance ; les entrées suivantes ne gardent que index, status et executionId. Absent sinon.
  • {{ data.<step>.simulatedLimit }} — number. Essai uniquement : le nombre d’itérations réellement exécutées, quand la liste était plus longue.
  • {{ data.<step>.total }} — number. Liste vide uniquement : 0, avec batchSize, concurrency et onItemError tels que réglés.
  • {{ data.<step>.summary }} — string. Un résumé d’une ligne dans la langue du membre, par exemple « 12 itérations traitées. » (avec summaryKey et summaryParams).

Example ​

Consigner chaque pièce jointe d’un mail entrant dans une ligne de table. Ajoutez un nœud Boucle :

source:      expression
items:       {{ email.attachments }}
concurrency: 1
onItemError: continue

Sur item, reliez Table — ajouter une ligne avec :

values: [{ "column": "fichier",    "value": "{{ data.item.filename }}" },
         { "column": "rang",       "value": "{{ data.index }}" },
         { "column": "expediteur", "value": "{{ email.from.email }}" }]

Sur done, ajoutez une Condition sur data.<step>.failed « est supérieur à » 0 pour prévenir quelqu’un quand une ligne n’a pas pu être écrite. Pour un mail à trois pièces jointes, le corps s’exécute trois fois, et après done, {{ data.<step>.succeeded }} vaut 3.

Tips ​

  • Le corps agit N fois. Un nœud Envoyer dans le corps envoie un mail par élément. C’est voulu ; vérifiez la liste avant de publier.
  • La liste doit être une liste. En mode expression, une valeur qui n’est pas un tableau (une chaîne vide due à un chemin mal orthographié, un objet) fait échouer l’étape avec node_invalid_param au lieu de lancer une seule itération. Un tableau vide n’est pas une erreur : la boucle prend done aussitôt, avec count à 0.
  • Bornes. « Nombre maximal d’itérations » (100 par défaut, 500 au plus) fait échouer la boucle avec loop_too_many_items quand la liste est plus longue : elle ne traite jamais une partie de la liste en silence. L’administrateur peut abaisser le plafond et le parallélisme de l’instance (LOOP_MAX_ITERATIONS, LOOP_MAX_CONCURRENCY, voir les variables d’environnement). Au plus 5 itérations tournent en parallèle, et un lot compte au plus 100 éléments.
  • Ordre. Avec « Itérations en parallèle » à 1 (le défaut), les itérations s’exécutent l’une après l’autre dans l’ordre de la liste. Au-delà, l’ordre n’est plus garanti.
  • Échecs. Avec « Arrêter la boucle » (défaut), aucune nouvelle itération ne démarre après un échec, celles déjà lancées vont au bout, et la boucle échoue avec loop_iteration_failed ; la politique d’erreur du nœud s’applique ensuite. Avec « Continuer et collecter l’erreur », la boucle va jusqu’au bout et prend done avec le status failed et les échecs listés dans items.
  • Budget de temps. Quand « Budget de temps (minutes) » est écoulé (60 par défaut, 24 heures au plus), la boucle prend done avec le status timeout. Les itérations déjà lancées vont quand même jusqu’au bout.
  • Essais. Seules les premières itérations s’exécutent (3 par défaut, LOOP_SIMULATED_MAX_ITERATIONS), et simulatedLimit le signale. Les effets du corps restent simulés.
  • Attendre et Approbation fonctionnent dans le corps : l’exécution de l’itération est suspendue, et la boucle l’attend.
  • La publication vérifie la forme. Le corps ne peut pas être vide, un nœud ne peut pas être à la fois dans le corps et après done, un nœud du corps ne peut pas recevoir de connexion venue de l’extérieur du corps (il voit déjà les données antérieures par la portée), et les boucles s’imbriquent sur deux niveaux au plus.