Français
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èsdone:done(toutes les itérations ont réussi),failed(certaines ont échoué, avec « Continuer et collecter l’erreur ») outimeout(budget de temps écoulé avant la fin).{{ data.<step>.count }}—number. Aprèsdone: le nombre d’itérations prévues (plafonné en essai).{{ data.<step>.succeeded }}—number. Aprèsdone: les itérations réussies.{{ data.<step>.failed }}—number. Aprèsdone: les itérations en échec ou annulées.{{ data.<step>.batchCount }}—number. Aprèsdone: les itérations réellement lancées.{{ data.<step>.items }}—array of { index, status, executionId, error, data }. Aprèsdone: une entrée par itération lancée.statusest le statut de l’exécution de l’itération,errorson code d’erreur en cas d’échec,datace 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èsdone:truequand lesdatacollectées ont dépassé le budget de l’instance ; les entrées suivantes ne gardent queindex,statusetexecutionId. 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, avecbatchSize,concurrencyetonItemErrortels 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. » (avecsummaryKeyetsummaryParams).
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: continueSur 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_paramau lieu de lancer une seule itération. Un tableau vide n’est pas une erreur : la boucle prenddoneaussitôt, aveccountà0. - Bornes. « Nombre maximal d’itérations » (100 par défaut, 500 au plus) fait échouer la boucle avec
loop_too_many_itemsquand 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 prenddoneavec lestatusfailedet les échecs listés dansitems. - Budget de temps. Quand « Budget de temps (minutes) » est écoulé (60 par défaut, 24 heures au plus), la boucle prend
doneavec lestatustimeout. 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), etsimulatedLimitle 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.