n8n-loops
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesen8n Loops
n8n 循环机制
Three meanings of "loop" map to three mechanisms:
- "Run this node for every item." Default. Most nodes loop automatically, so do nothing.
- "Run this node once with all items, not once per item." The setting (single boolean).
executeOnce - "Process items in explicit batches with control flow between iterations." The node (formerly
Loop Over Items).Split In Batches
For paginated APIs, the HTTP Request node has built-in pagination. Almost always preferable to a hand-built page-counting loop.
“循环”的三种含义对应三种实现机制:
- 「为每个条目运行此节点。」 默认行为。大多数节点会自动循环,无需额外操作。
- 「一次性运行此节点,处理所有条目,而非逐条目运行。」 使用设置(布尔值开关)。
executeOnce - 「通过显式批处理处理条目,并在迭代间控制流程。」 使用节点(原
Loop Over Items)。Split In Batches
对于分页API,HTTP Request节点内置分页功能。通常比手动构建的页数计数循环更优。
The model: items are an array
核心模型:条目以数组形式流动
Data flows between nodes as an array of items, each . 50 items = 50-entry array.
{ json: {...}, binary?: {...} }Default: a node runs once per item. An HTTP Request with 50 input items fires 50 requests and outputs 50 result items. This is the implicit loop most workflows rely on.
The input array is the loop. Control iteration by controlling the array.
数据在节点间以条目数组的形式传递,每个条目结构为。50个条目即对应50元素的数组。
{ json: {...}, binary?: {...} }默认行为:节点逐条目运行。一个带有50个输入条目的HTTP Request节点会发起50次请求,并输出50个结果条目。这是大多数工作流依赖的隐式循环。
输入数组即为循环的载体。通过控制数组来实现对迭代的控制。
Non-negotiable
必须遵守的规则
executeOnce: true$input.all()$('Node').all().map().filter().reduce()Counter-case: combined with another node's (a per-item lookup, e.g., ) is real per-item work and should keep off. See the skill's executeOnce section for the full distinction.
.all().item$('Get Tags').all().filter(tag => $('Search Posts').item.json.tag_ids.includes(tag.json.id))executeOncen8n-expressions当节点需要每次工作流运行触发一次而非逐条目触发时,务必设置。包括任何通过 / 结合 / / 来聚合整个数据集的表达式(若不设置,聚合操作会针对上游N个条目执行N次,通常会在下游产生N个重复结果)。还包括单次通知、聚合写入、汇总消息等场景。
executeOnce: true$input.all()$('Node').all().map().filter().reduce()反例:结合另一个节点的(逐条目查找,例如)属于真正的逐条目操作,应保持为关闭状态。详见技能中的executeOnce章节以明确区分。
.all().item$('Get Tags').all().filter(tag => $('Search Posts').item.json.tag_ids.includes(tag.json.id))executeOncen8n-expressionsStrong defaults
推荐默认实践
- Don't build a loop when default iteration suffices. Most nodes (HTTP Request, native service nodes, Set, IF/Switch) run once per input item automatically: N items in, N runs. To make N HTTP calls or create N records, just connect the source to the node. Don't reach for unless you need per-iteration control. (Note:
Loop Over Itemsis the exception. It defaults to a single all-items batch. SeeExecute Workflowforn8n-subworkflows.)mode: 'each' - For paginated APIs, use HTTP Request's built-in pagination. Don't reinvent with + manual
Loop Over Itemsunless the API is genuinely odd. See$pageCount.references/HTTP_PAGINATION.md - is for explicit batching or per-iteration control (rate limiting, per-batch error recovery, stateful chunks, polling). See
Loop Over Items.references/LOOP_OVER_ITEMS.md
- 当默认迭代足够时,不要手动构建循环。大多数节点(HTTP Request、原生服务节点、Set、IF/Switch)会自动逐输入条目运行:N个输入条目对应N次运行。要发起N次HTTP调用或创建N条记录,只需将源节点连接到目标节点即可。除非需要迭代间控制,否则不要使用。(注意:
Loop Over Items是例外。它默认以全条目批处理模式运行。详见Execute Workflow中的n8n-subworkflows设置。)mode: 'each' - 对于分页API,使用HTTP Request的内置分页功能。除非API行为特殊,否则不要用+ 手动
Loop Over Items来重复造轮子。详见$pageCount。references/HTTP_PAGINATION.md - 用于显式批处理或迭代间控制(限频、批处理错误恢复、有状态分块、轮询)。详见
Loop Over Items。references/LOOP_OVER_ITEMS.md
Decision tree: which mechanism do I need?
决策树:选择合适的循环机制
Need to do something for each item?
├── Default per-item iteration is enough
│ └── Just connect the node. Done.
│
├── The node should run once total, not once per item?
│ └── Set executeOnce: true on the node
│
├── Paginated API (multiple HTTP calls to fetch all pages)?
│ └── Use HTTP Request's Pagination option (see references/HTTP_PAGINATION.md)
│
├── Need explicit batching (rate limit, chunk size, per-batch error handling)?
│ └── Use Loop Over Items node (see references/LOOP_OVER_ITEMS.md)
│
└── Need to recurse / repeat with state until a condition is met?
└── Loop Over Items with Reset, OR a sub-workflow that calls itself.
Both are advanced patterns; see references/LOOP_OVER_ITEMS.md.需要为每个条目执行操作吗?
├── 默认逐条目迭代足够
│ └── 直接连接节点即可。完成。
│
├── 节点需总共运行一次,而非逐条目运行?
│ └── 在节点上设置executeOnce: true
│
├── 分页API(需多次HTTP调用获取所有页面)?
│ └── 使用HTTP Request的分页选项(详见references/HTTP_PAGINATION.md)
│
├── 需要显式批处理(限频、分块大小、批处理错误处理)?
│ └── 使用Loop Over Items节点(详见references/LOOP_OVER_ITEMS.md)
│
└── 需要递归/带状态重复直到满足条件?
└── 使用带Reset的Loop Over Items,或调用自身的子工作流。
两者均为高级模式;详见references/LOOP_OVER_ITEMS.md。executeOnce
: the single-fire setting
executeOnceexecuteOnce
:单次触发设置
executeOnceEvery node's Settings tab has an Execute Once toggle. When on, the node runs once using only the first input item.
ts
{
name: 'Aggregate Slack',
type: 'n8n-nodes-base.slack',
parameters: { /* ... */ },
executeOnce: true,
}When to use it:
- Notifications and aggregate writes. A "summary message" shouldn't fire 100 times because 100 items came in.
- Counters, totals, reports. Anything computing etc. should run once.
$input.all().length - Expressions aggregating across the full array via /
$input.all(). Otherwise the aggregate runs per upstream item. (Per-item lookups using$('Node').all()filtered by another node's.all()are the counter-case, see.item.)n8n-expressions
When NOT to use it:
- Per-item operations. One notification per item is the default and usually correct.
- HTTP requests fanning out per item. You want one call per item.
Most common mistake: forgetting on an aggregate node, then seeing the same message fire 50 times after a fan-out.
executeOnce每个节点的设置选项卡都有一个Execute Once开关。开启后,节点仅使用第一个输入条目运行一次。
ts
{
name: 'Aggregate Slack',
type: 'n8n-nodes-base.slack',
parameters: { /* ... */ },
executeOnce: true,
}适用场景:
- 通知与聚合写入。「汇总消息」不应因传入100个条目而触发100次。
- 计数器、总计、报表。任何计算等操作的节点应仅运行一次。
$input.all().length - 通过/
$input.all()聚合整个数组的表达式。否则聚合操作会针对每个上游条目执行。(通过$('Node').all()结合另一个节点的.all()进行的逐条目查找是反例,详见.item。)n8n-expressions
不适用场景:
- 逐条目操作。为每个条目发送一条通知是默认行为,通常是正确的。
- 逐条目发起HTTP请求。你需要为每个条目发起一次调用。
最常见错误:在聚合节点上忘记设置,导致扇出后相同消息触发50次。
executeOnceWhen the implicit loop bites you
隐式循环的常见问题
Default per-item iteration is great until it isn't. Common surprises:
默认逐条目迭代通常很好,但也会有意外情况:
A "single" config node fires per item
“单个”配置节点逐条目触发
A node after a fan-out runs once per item, producing N copies of the same constants. Usually fine, but expensive expressions (long , Luxon parse) run N times. Move the Set above the fan-out, or set .
SetJSON.stringifyexecuteOnce: true扇出后的节点会逐条目运行,生成N个相同常量的副本。通常没问题,但耗时的表达式(如长、Luxon解析)会执行N次。可将Set节点移至扇出之前,或设置。
SetJSON.stringifyexecuteOnce: trueAn aggregate Code node runs N times
聚合Code节点运行N次
A Code node reading to compute a sum runs once per upstream item without , producing N identical items. Set .
$input.all()executeOnce: trueexecuteOnce: true读取计算总和的Code节点,若未设置,会针对每个上游条目运行一次,生成N个相同的条目。设置即可解决。
$input.all()executeOnce: trueexecuteOnce: trueA respond-to-webhook fires twice
响应Webhook触发两次
Most painful version. Respond-to-Webhook fires per input item, and two branches converging without a merge fire it twice: first response wins, the rest log errors. Merge first, or ensure only one branch reaches the responder. See .
n8n-connectionsFAN_OUT_FAN_IN.md最棘手的情况。Respond-to-Webhook会逐输入条目触发,若两个分支未合并就到达响应节点,会触发两次:第一个响应生效,其余会记录错误。先合并分支,或确保只有一个分支到达响应节点。详见的。
n8n-connectionsFAN_OUT_FAN_IN.mdAn LLM call fires N times when you wanted one summary
LLM调用触发N次而非一次汇总
Same shape as the aggregate Code node. An LLM node with in its prompt makes N identical calls, costs N tokens, returns N identical answers without .
$input.all()executeOnce: true与聚合Code节点情况相同。提示中包含的LLM节点,若未设置,会发起N次相同调用,消耗N倍令牌,返回N个相同结果。
$input.all()executeOnce: trueWhen to reach for Loop Over Items
Loop Over Items何时使用Loop Over Items
Loop Over ItemsDefault iteration handles most cases. Use for:
Loop Over Items- Rate limiting. "Process 10 at a time, 1s wait between batches."
- Batched API calls with array bodies. "Send 50-item chunks to /bulk."
- Per-batch error handling. "If a batch fails, log and continue."
- Stateful iteration. "Each iteration depends on the previous output."
- Polling a long-running job. "Start, check status every 30s until done or capped." Uses plus a
reset: trueceiling.$runIndex - Per-item multi-branch with aggregation. "For each input, run transforms in parallel, merge, then aggregate." The done output (index 0) carries the result.
For wiring details, the output-index gotcha (output 0 = done, output 1 = loop), and worked examples, see .
references/LOOP_OVER_ITEMS.md默认迭代可处理大多数场景。在以下情况使用:
Loop Over Items- 限频。「每次处理10个条目,批次间隔1秒。」
- 带数组请求体的批处理API调用。「向/bulk发送50条目的分块。」
- 批处理错误处理。「若批次失败,记录日志并继续。」
- 有状态迭代。「每次迭代依赖前一次的输出。」
- 轮询长时间运行的任务。「启动任务,每30秒检查状态,直到完成或达到上限。」需使用结合
reset: true上限。$runIndex - 逐条目多分支聚合。「针对每个输入,并行运行转换操作,合并后再聚合。」完成输出(索引0)携带结果。
有关接线细节、输出索引陷阱(输出0 = 完成,输出1 = 循环)及示例,详见。
references/LOOP_OVER_ITEMS.mdWhen NOT to reach for Loop Over Items
Loop Over Items何时不使用Loop Over Items
Loop Over ItemsThe most common rationalization: "I need to wait for all items to finish before the next step, so I'll add Loop Over Items and use the output." You don't need Loop Over Items for that. Default per-item iteration already waits: each item flows through the full downstream chain before the next item starts, and the post-loop node never fires "early."
doneThe cure for that mistake is almost always: delete the Loop Over Items node, change nothing else, ship. That is Scenario 1 below, and it covers the majority of cases.
The four scenarios are independent. Read them as separate decisions, not as alternatives that all "replace" Loop Over Items. Most builds hit Scenario 1 and are done. Scenarios 2 and 3 only enter the picture when their specific goal applies. Scenario 4 is the narrow case where Loop Over Items actually earns its place.
最常见的错误理由:「我需要等所有条目处理完再进行下一步,所以添加Loop Over Items并使用输出。」你不需要为此使用Loop Over Items。默认逐条目迭代已经会等待:每个条目会先走完下游完整流程,再处理下一个条目,循环后的节点绝不会「提前」触发。
done解决此错误的方法几乎总是:删除Loop Over Items节点,其余保持不变,即可部署。这属于下文的场景1,覆盖大多数情况。
四个场景相互独立。将它们视为独立决策,而非替代Loop Over Items的方案。大多数构建会采用场景1即可完成。场景2和3仅在特定目标适用时才会用到。场景4是Loop Over Items真正适用的窄场景。
Scenario 1: default per-item iteration (the default, most common)
场景1:默认逐条目迭代(默认,最常见)
Source emits N items, per-item processor runs N times, downstream chain follows. No Loop Over Items, no , no Aggregate. Just connect the nodes.
executeOnce[Source: 20 items]
→ [Per-item processor] # default iter, runs 20 times
→ [Next step] # runs after each item, in orderIf a was added here "to wait for all items" or "to make the next node run for each item," delete the Loop Over Items node and wire source straight to processor. Do not replace it with anything. Default iteration already does the job. The exception is (sub-workflow): it defaults to a single all-items batch, so per-item invocation needs on that node, not a Loop. See .
Loop Over Items + doneExecute Workflowmode: 'each'n8n-subworkflows源节点输出N个条目,逐条目处理器运行N次,下游流程跟进。无需Loop Over Items、无需、无需聚合。只需连接节点即可。
executeOnce[源节点:20个条目]
→ [逐条目处理器] # 默认迭代,运行20次
→ [下一步] # 每个条目处理完后触发,按顺序执行如果此处添加是为了「等待所有条目完成」或「让下一个节点逐条目运行」,请删除Loop Over Items节点,将源节点直接连接到处理器。无需替换为任何其他节点。默认迭代已完成该工作。例外情况是(子工作流):它默认以全条目批处理模式运行,因此逐条目调用需在该节点上设置,而非使用循环。详见。
Loop Over Items + doneExecute Workflowmode: 'each'n8n-subworkflowsScenario 2: a downstream node should fire once total (executeOnce: true
)
executeOnce: true场景2:下游节点需总共触发一次(executeOnce: true
)
executeOnce: trueIndependent of Scenario 1. Triggered only when there is a SPECIFIC downstream node whose job is once-per-run, not once-per-item: one digest email after 20 papers process, one summary write after the loop, one final Slack notification.
Set on that node. The node receives all upstream items but runs once. This is a per-node setting, not a Loop replacement: the per-item processor in Scenario 1 still runs N times, and only this one downstream node collapses.
executeOnce: true独立于场景1。仅当存在特定下游节点需要每次工作流运行触发一次而非逐条目触发时才使用:20篇文档处理完成后发送一封摘要邮件,循环结束后进行一次汇总写入,发送最后一条Slack通知。
在该节点上设置。节点会接收所有上游条目,但仅运行一次。这是节点级设置,而非循环替代方案:场景1中的逐条目处理器仍会运行N次,仅该下游节点会合并为单次运行。
executeOnce: trueScenario 3: a node needs the items as a single array (Aggregate)
场景3:节点需要条目作为单个数组(聚合)
Independent of Scenario 1. Triggered only when a downstream node's input contract is a list, not per-item invocations (e.g., a node taking a JSON array body, an LLM prompt that needs the whole list).
Use the Aggregate node to collapse the per-item stream into one item containing the array. Again, not a Loop replacement.
独立于场景1。仅当下游节点的输入要求为列表而非逐条目调用时才使用(例如,接收JSON数组请求体的节点,需要完整列表的LLM提示)。
使用Aggregate节点将逐条目流合并为包含数组的单个条目。同样,这不是循环替代方案。
Scenario 4: genuine batching (the only time Loop Over Items earns its place)
场景4:真正的批处理(Loop Over Items唯一适用的场景)
Rate limiting (process N at a time with a Wait between batches), chunked bulk API calls (POST 50-item arrays to ), per-batch error handling, polling a long-running job with and a ceiling, stateful iteration where each batch depends on the previous output.
/bulkreset: true$runIndex"Wait for items to finish" does not qualify. Default iteration already does that.
限频(每次处理N个条目,批次间等待)、分块批量API调用(向/bulk POST 50条目的数组)、批处理错误处理、使用和上限轮询长时间运行的任务、每次批次依赖前一次输出的有状态迭代。
reset: true$runIndex「等待条目完成」不属于此场景。默认迭代已完成该工作。
Quick disambiguation
快速区分
If your only reason for the Loop is "wait for items / run for each item," you are in Scenario 1. Delete the Loop. Do not add or Aggregate as a substitute. They solve different problems and are only added when their own scenario applies.
executeOnce如果使用循环的唯一理由是「等待条目完成/逐条目运行」,则属于场景1。删除循环。不要用或聚合替代。它们解决的是不同问题,仅在各自场景适用时才添加。
executeOnceWhen to reach for HTTP pagination
何时使用HTTP分页
Three common page shapes:
- Next-URL in response. Each response includes a link.
next - Page number/cursor parameter. Bump or
?page=Neach call.?cursor=... - Stop on empty page or specific status.
HTTP Request handles all natively via its Pagination option: set the mode, give a next-page expression, and the node loops internally, returning a single output array of all pages' items.
Don't reinvent with + manual unless the API does something the built-in modes can't express.
Loop Over Items$pageCountSee .
references/HTTP_PAGINATION.md三种常见的页面形式:
- 响应中包含Next-URL。每个响应包含一个链接。
next - 页码/游标参数。每次调用递增或
?page=N。?cursor=... - 空页面或特定状态时停止。
HTTP Request节点通过其Pagination选项原生支持所有这些形式:设置模式,提供下一页表达式,节点会在内部循环,返回包含所有页面条目的单个输出数组。
除非API行为特殊到内置模式无法表达,否则不要用 + 手动重复造轮子。详见。
Loop Over Items$pageCountreferences/HTTP_PAGINATION.mdSub-workflow recursion
子工作流递归
For genuinely recursive work (tree walking, retry-with-backoff, "process this and its children"), a self-calling sub-workflow is cleaner than with . Input parameters carry recursion state.
Loop Over ItemsResetSub-workflow: Walk Tree
inputs: { node_id, depth }
body: process node, look up children, for each child call self with depth+1Watch recursion depth. n8n has nested-execution limits. For deep recursion, a queue + flat loop beats true recursion.
对于真正的递归工作(遍历树、退避重试、「处理此条目及其子条目」),调用自身的子工作流比带的更简洁。输入参数携带递归状态。
ResetLoop Over Items子工作流:遍历树
输入:{ node_id, depth }
主体:处理节点,查找子节点,为每个子节点调用自身并传入depth+1注意递归深度。n8n有嵌套执行限制。对于深度递归,队列+扁平循环优于真正的递归。
Reference files
参考文件
| File | Read when |
|---|---|
| Configuring the Loop Over Items node, batching, rate limiting, stateful iteration |
| Calling a paginated API, configuring HTTP Request pagination modes |
| 文件 | 阅读场景 |
|---|---|
| 配置Loop Over Items节点、批处理、限频、有状态迭代 |
| 调用分页API、配置HTTP Request分页模式 |
Anti-patterns
反模式
| Anti-pattern | What goes wrong | Fix |
|---|---|---|
Adding | Workflow harder to read for no benefit, and loop output vs done output gets miswired | Just connect the node directly and let default iteration handle it |
Aggregate Code node without | Same aggregate computed N times, output has N identical items | Set |
Manual pagination loop with | Reinvents what HTTP Request does natively, with brittle stop conditions | Use HTTP Request's |
| Sending one Slack message per item when you wanted a summary | Slack channel floods, rate limits hit, embarrassment | |
Two branches both reach | Responds twice, downstream callers see errors | Merge before the responder, or ensure only one branch reaches it |
| Infinite loop, n8n eats memory until the execution is killed | Always have a clear termination condition. Prefer HTTP pagination for paged APIs |
Nesting one | Broken at runtime, validation passes | Move the inner loop into a sub-workflow called per outer iteration. See |
| 反模式 | 问题 | 修复方案 |
|---|---|---|
当默认迭代已实现循环时,仍添加 | 工作流可读性降低且无收益,还可能误接循环输出与完成输出 | 直接连接节点,让默认迭代处理 |
聚合Code节点未设置 | 相同聚合操作执行N次,输出包含N个相同条目 | 设置 |
使用 | 重复造HTTP Request原生支持的功能,终止条件脆弱 | 使用HTTP Request的 |
| 逐条目发送Slack消息而非汇总消息 | Slack频道被刷屏,触发限频,造成困扰 | 在Slack节点上设置 |
两个分支均到达 | 响应两次,下游调用方看到错误 | 在响应节点前合并分支,或确保只有一个分支到达响应节点 |
| 无限循环,n8n占用内存直到执行被终止 | 始终设置明确的终止条件。分页API优先使用HTTP分页 |
在同一工作流中嵌套 | 运行时出错,但验证通过 | 将内层循环移至子工作流,在外层迭代时调用该子工作流。详见 |