拓冰建站拓冰建站
首页 / 资讯中心 / 正文

n8n循环节点Loop Over Items详解:批量数据处理与邮件发送实战

用 n8n 做自动化几乎都会撞上同一个需求上游一次性返回了几百条数据你却希望一条一条处理。给用户挨个发邮件、按订单逐条查物流、把接口返回的列表分批写入第三方系统……这些场景里Loop Over Items 就是那个“救火队员”。它做的事情不复杂把 n8n 工作流里的一组 items 按你指定的批次大小逐轮送进循环体每轮只处理一条或一小批数据全部处理完后再触发后续流程。如果你是刚接触 n8n 不久可能对这个节点既熟悉又陌生——节点面板里看得到它但不确定它和普通节点的区别如果你已经用过一段时间大概率也踩过“循环里字段丢了”“循环次数不对”“不知道怎么在循环里引用当前这一条数据”之类的坑。这篇文章我会从实际工作流搭建的角度把 Loop Over Items 的原理、参数、真实案例和排障经验一次讲透尽量让你看完就能直接上手。1. Loop Over Items 是什么解决什么问题1.1 它在 n8n 流程中的位置Loop Over Items 是 n8n 内置的 Flow流程控制类节点不需要额外安装社区节点。你打开左侧节点面板在 Flow 分类下就能看到它。从名字也能猜到它专门负责“遍历”把输入节点传来的 items 数组拆开按照设定的批次大小一轮一轮地发给后面的节点去处理。这里有一个 n8n 的基础概念必须先说清楚n8n 中几乎所有普通节点处理的都是“一组数据”而不是“一条数据”。比如一个数据库查询节点查出了 100 行用户记录它向下游输出的不是 1 个包含 100 行的整体对象而是 100 个 item每个 item 是一条用户记录。下一个节点拿到这 100 个 item会对每个 item 各执行一次逻辑。这听起来好像天然就已经是循环了为什么还要 Loop Over Items区别在于普通节点拿到 100 个 item 时虽然内部会逐个处理但对使用者来说是一个整体批次中间没有“轮次”的概念你没法控制每一轮之间的节奏也没法暂停下来做点别的。Loop Over Items 则把这个过程显式化了它像一个闸门一次只放一批数据过去让后面的节点处理完这一批再放下一批。这种“显式的轮次控制”正是批量自动化场景里最需要的东西。1.2 没有它时你会遇到什么麻烦我早期用 n8n 时不太理解这个节点觉得“反正下游节点本来就会对每个 item 跑一遍逻辑直接连过去不就得了”。后来接到一个需求从 CRM 里取回 500 个待回访客户需要逐个调用第三方接口查询客户的最近订单再根据结果发送回访短信。第一次我图省事把查询订单的 HTTP Request 节点直接接在 CRM 查询后面结果第三方接口瞬间被打爆返回一大堆 429 限流错误工作流直接失败而且失败后根本不知道是哪个客户、哪一批请求出的问题。这就是没有循环控制时的典型痛点大批量数据一次性涌入外部系统扛不住中间某一条数据异常整个批次全部失败排障像大海捞针遇到需要“上一条处理完才能处理下一条”的业务逻辑更没有合适的位置做等待和判断。Loop Over Items 解决的就是这一类问题——它让批量数据处理从“粗放式的一梭子”变成了“可控的一轮一轮”每条数据在什么时间点处理、处理到第几条了、这一批有没有异常都变得清晰可见。1.3 它擅长和不擅长的场景根据我的实际使用经验Loop Over Items 适合下面这几类场景需要对上游返回的多条数据逐条执行同一套逻辑比如批量发送邮件、短信、站内通知调用的外部 API 有明确的频率限制需要控制请求节奏每条数据的处理结果会影响下一条数据的参数必须串行执行希望某一条处理失败时能快速定位到具体是哪条数据引起的。但也要说句公道话它并不是所有批量场景的最优解。如果只是想把一个数组拆成多个小数组继续分发没有“逐轮等待”的需求直接用普通节点处理可能更快如果数据量达到几万条甚至更多一个工作流从头到尾遍历完执行时间和资源占用都很可观这种时候更适合拆成多个子任务或者用外部队列来控制。简单说Loop Over Items 是帮你把“批量任务变成可控任务”的节点而不是帮你无脑塞下无限数据的节点。2. 参数与数据流准备把要遍历的数据理清楚2.1 理解 n8n 的 items 数组是循环的基础动手配置前务必要确认清楚上游节点到底输出的是什么结构。Loop Over Items 遍历的对象是输入节点传来的 items 数组。你可以把它理解成一列火车车厢每节车厢就是一个 item里面装着一个 JSON 对象Loop Over Items 的作用就是决定一次放几节车厢出站。以一个实际的数据库查询为例。假设你用 MySQL 节点执行了SELECT email, user_name FROM users WHERE status pending查询结果是 30 条未激活用户。在 n8n 的执行数据里这个节点会输出 30 个 item每个 item 大概是这样的结构{ email: user01example.com, user_name: 张三 }如果把这 30 个 item 直接接到 Loop Over Items 上循环节点会把它当成“需要遍历的清单”。你在搭建流程之前可以先在前面随便接一个 Set 节点或者直接查看上游节点的执行结果确认字段名、字段数量、数据类型是否符合预期。不要嫌这一步麻烦我见过太多人循环配了半天不生效最后发现是上游查询的字段名和后续表达式里写的不一致。2.2 Batch Size 到底该怎么调Loop Over Items 最核心的参数是 Batch Size也就是“每轮循环往后续节点送几条数据”。默认值是 1含义是每次迭代只把一条 item 交给后面的节点处理。如果输入有 30 条数据Batch Size 为 1那工作流会执行 30 轮循环Batch Size 改为 10则 30 条数据会被分成 3 轮每轮送 10 条过去。这里有一个容易误解的地方Batch Size 为 10 不是说“后面节点每轮只处理 10 条里的一条”而是“后面节点这一轮收到的是一个包含 10 条 item 的数组”它会对这 10 条 item 分别执行逻辑。如果你用的是 SMTP Send、HTTP Request 这类天然支持多 item 的节点这一轮就会连续发送 10 封邮件或发起 10 个请求。Batch Size 怎么选取决于你的业务诉求对比项Batch Size 1Batch Size 10迭代轮数等于 items 总条数等于总条数 / 10向上取整单轮内下游处理量每次只处理 1 条每轮处理 10 条请求节奏最容易控制逐条推进吞吐量更高但突发压力更大异常排查难度低能精准定位到某一条高一条出错整轮都可能受影响适合场景对外部 API 限流敏感、需要逐条确认批量导入、批量归档、内部系统调用我个人在面对外部 API 时默认从 Batch Size 1 开始调。先把一条数据的完整链路跑通确认识别率、参数、返回结构都正常再根据接口的限流情况决定是否调大批次。调批次之前不妨去读一下你调用的那个 API 的频率限制文档不同服务商差异很大有的允许每秒几十次有的每分钟只给 60 次额度用 Batch Size 硬怼一定会出事。2.3 Loop 输出和 Done 输出千万别接反Loop Over Items 节点在编辑器右侧通常有两个输出口一个是 loop 输出另一个是 done 输出。这两个输出的含义完全不同很多新手第一次用都会在这里栽跟头。loop 输出是“每一轮循环的主输出”后面连接的业务逻辑节点比如发邮件的 SMTP 节点、调接口的 HTTP Request 节点都要接在这个输出上。每执行一轮循环这些节点就会被触发一次。done 输出则是“所有循环全部结束之后”才触发的完成信号整个循环生命周期里它只会触发一次。如果你希望循环跑完以后再做一个统一的收尾动作比如发送一条“全部处理完成”的群通知、把处理结果汇总写回数据库就应该把收尾节点接在 done 输出上。一个很常见的错误是有人把“循环结束后发送通知”的节点也接到了 loop 输出上结果每处理一条数据就收到一条通知。这不是 n8n 有 bug而是输出接口选错了。接线的时候留意一下连接点提示n8n 会明确问你要连接到哪个输出。注意如果循环内的业务节点执行失败导致整个工作流中途退出done 输出不会触发。所以不要把“必须执行”的清理动作只挂在 done 分支上最好配合 n8n 的 Error Workflow 或额外的兜底机制。2.4 和 Split In Batches 节点的关系如果你用的 n8n 版本稍微老一点可能还会在节点面板里看到 Split In Batches 这个节点。它和 Loop Over Items 的定位高度重叠都是把输入数据按照批次拆分后逐轮输出。n8n 官方后来的建议是优先使用 Loop Over Items因为它的语义更清晰也能覆盖 Split In Batches 的主要使用场景。我的建议是新写工作流时直接用 Loop Over Items不要再纠结 Split In Batches。迁移旧工作流时留意一下循环内部对数据的引用方式可能略有不同但只要数据流不变替换成本通常很低。这个“一个功能两代节点”的情况也提醒我们看网上老教程时先确认一下对方的 n8n 版本避免照着旧界面操作半天对不上。3. 实操循环逐条生成权益码并发送邮件3.1 场景设定与整体流程为了把用法讲透我设计了一个真实感比较强的案例。假设你现在有一个 n8n 工作流目标是每天早上从会员表里找出 100 个本月还没领过优惠券的用户逐个调用内部权益接口为每个用户生成一个专属优惠码再给每个用户发送一封带优惠码的邮件。这个案例里最核心的约束是内部权益接口有调用频率限制不能一次性把 100 个请求全打过去邮件内容里的优惠码又必须和用户一一对应不能张冠李戴。这正好是 Loop Over Items 发挥价值的标准场景。整体流程可以这样组织上游节点查询待发用户列表得到 N 个用户 itemLoop Over Items 节点接收这个列表设置 Batch Size 1循环体内先接一个 HTTP Request 节点调用内部权益接口为当前用户生成优惠码再接一个 SetEdit Fields节点把邮件需要的字段组装到一起最后接一个 SMTP 节点给当前用户发送邮件所有用户处理完后通过 done 输出发送一条汇总通知。3.2 把输入数据准备好第一步是拿到待处理用户列表。你可以用 MySQL、Postgres、HTTP Request、Google Sheets 等任意方式作为数据源。这里关键不是用什么节点而是保证输出的 item 结构足够清晰。假设上游查询出来每个用户 item 长这样{ user_id: u_1001, email: member01example.com, name: 林晓, member_level: gold }如果你第一次搭这个流程我强烈建议先用一个数据量极小的输入来验证比如在 SQL 查询里加LIMIT 3或者先用测试数据。不要一上来就处理 100 条真实数据否则一旦流程有问题邮件可能已经发出去几十封了很难挽回。测试通过后再把数据量放宽这是批量任务的基本安全姿势。3.3 接入 Loop Over Items 并配置批次大小把用户列表节点连接到 Loop Over Items 节点。点击循环节点在参数面板里找到 Batch Size先填 1。前面解释过Batch Size 1 表示每轮循环只放行一个用户 item 进入循环体整条链路串行执行这样既能控制对内部权益接口的请求频率也便于定位是哪条数据出了问题。如果后续测试发现内部接口其实很扛得住想提速可以把 Batch Size 调到 5 或 10。但记得要重新评估一下“邮件发送”这步的节奏批量发送邮件时如果频率太高很容易被邮件服务商判定为垃圾邮件行为所以我个人做邮件类场景时几乎永远保持 Batch Size 1最多在邮件服务商侧开通专门的批量发送通道。3.4 在循环体内调用接口并保留原始字段循环体里的第一个业务节点是 HTTP Request。这里有个很容易踩的坑默认情况下HTTP Request 节点会把上游传进来的用户 item “替换”成接口响应的内容。也就是说进入 HTTP Request 时你还有email、name这些字段等它请求完权益接口输出给下一个节点的可能就只剩{code: GOLD-2024-XXXX}之类的接口返回值了。如果不做任何处理下一步组装邮件时就会发现优惠码拿到了但用户邮箱和姓名不见了邮件根本不知道发给谁。为了解决这个问题有两个常用手段。第一种是在 HTTP Request 节点上开启“包含输入数据”Append Input Data 或类似选项让输出里既保留原始用户字段又带上接口返回的字段第二种是在 HTTP Request 后面加一个 Set 节点手动把需要继续传递的字段重新拼接出来。我推荐第二种因为它的表达最明确也不依赖 HTTP Request 节点不同版本里选项名称的差异。操作上在 HTTP Request 后面接一个 SetEdit Fields节点把输出字段配置成邮件发送需要的完整结构to字段填{{ $(Loop Over Items).item.json.email }}用于取当前循环用户 item 里的邮箱user_name字段填{{ $(Loop Over Items).item.json.name }}coupon_code字段填{{ $json.code }}这里$json是 HTTP Request 节点输出的接口响应内容。这样组合之后Set 节点输出的就是一条同时包含收件人信息和优惠码的完整 item下游节点处理起来就非常干净了。3.5 用 SMTP 节点完成逐封发送邮件发送这一步先说一个常见疑问n8n 本身没有“内置邮箱”它靠的是节点去连接外部邮件服务。最通用的方案是 SMTP 节点你只要在 n8n 的 Credentials 里配置好 SMTP 服务地址、账号、密码或授权码就能用它发邮件。n8n 里也可以接入 Gmail、Outlook、SendGrid 等专门的邮件节点本质都是靠对应的凭据把邮件交给第三方服务发送。在我们的循环工作流中Set 节点后面接 SMTP Send或你选择的邮件发送节点。在邮件的收件人、主题、正文里直接用{{ $json.to }}、{{ $json.user_name }}、{{ $json.coupon_code }}这些变量引用。因为此时 Batch Size 1SMTP 节点每一轮只会收到一条 item所以它每轮只发一封邮件。外部接口被“限流”的问题也从根源上被循环节奏控制住了。如果你的实际业务流程不需要调用接口而是直接把数据库里查出来的一批用户逐封发邮件那整个循环体甚至可以只由一个 SMTP 节点组成。Loop Over Items 会把每个用户 item 依次送进 SMTP 节点每次发一封。这就是这个节点最朴素的用法很多“通知类”工作流就是这么搭起来的。3.6 查看执行日志和验证结果配好之后先跑一次测试。n8n 的执行日志是排查批量任务最有力的工具。点击执行后在 executoins 列表里打开这次工作流执行记录你会看到 Loop Over Items 节点下面有很多次迭代记录或者能看到它把输入列表切成了一条一条往下传。你可以展开任意一次迭代确认当前的email、user_id是否正确HTTP Request 返回的优惠码有没有正常赋值SMTP 节点是否返回了发送成功状态。这里分享一个我自己的验证习惯即使 Batch Size 1第一次跑正式数据时也一定先选 5 个以内用户。跑完以后立刻去收件箱确认邮件内容尤其是优惠码和用户名是否对得上。如果内容有误马上停掉后续流程回头检查 Set 节点里的字段映射如果内容没问题再放开完整的数据量。邮件这类“发出去就收不回”的操作前置验证绝对不能省。3.7 邮箱发送服务选择的补充既然标题相关热词里反复提到 n8n 能通过什么邮箱发邮件我顺带把这块也聊透一点。n8n 发邮件的常见方案大概是这三种自建或企业邮箱的 SMTP 服务用 SMTP 节点发送成本低适合内部通知和中小量邮件但要注意服务商对每日发送量和频率的限制专业邮件发送服务比如 SendGrid、Postmark、Amazon SES适合营销邮件、大规模事务邮件有更好的送达率和反垃圾信誉Gmail 等个人邮箱适合测试和小流量场景不适合生产环境大批量发送很容易触发风控。在 Loop Over Items 里逐封发送时如果你用的是普通 SMTP 邮箱千万不要把 Batch Size 调太高也不要完全省略每条之间的节奏。即便 Batch Size 1n8n 的执行速度也可能比你想象中快很多眨眼间就把几十封邮件发出去了。如果邮件服务商对发送频率敏感可以考虑在循环体内加一个 Wait 节点做延时或者退一步把任务拆分成多次触发。批量邮件的核心技术从来不是“能不能发”而是“发多少、多快、会不会被当成垃圾邮件”。4. 循环内部的数据引用与高级玩法4.1 循环里到底怎么引用“当前这条”数据循环场景里最出问题的就是数据引用。很多人以为进入循环体之后随便在哪个节点里用$json.email都能取到当前用户邮箱其实这取决于你当前看到的这个节点的输入到底是什么。n8n 的表达式里$json代表的是“当前节点收到的那条输入数据”。在循环体里的第一个节点它收到的确实就是当前迭代的那条 item所以直接用{{ $json.email }}没问题。但如果在 HTTP Request 或某些转换节点之后再用$json它代表的可能就是前一个节点的输出不再是循环开始时那条用户数据了。要引用循环开始时的那条原始数据更稳妥的方式是指定“循环节点”本身。比如循环节点如果叫 Loop Over Items那么在许多 n8n 版本里可以这样写{{ $(Loop Over Items).item.json.email }}旧版兼容写法也有人用{{ $node[Loop Over Items].json.email }}两者的本质都是“从 Loop Over Items 节点当前这一轮迭代的输出里取 email 字段”。因为你的 Batch Size 1每一轮 Loop Over Items 输出给循环体的只有一条 item所以这么取到的就是当前正在处理的这条用户数据。如果 Batch Size 调成了 10那这个表达式取到的会是当前轮次里 Loop 节点输出的第一条 item而不是随机一条你需要理解这个语义再使用。4.2 被上游节点覆盖的数据怎么找回来上一节提到的 HTTP Request 覆盖输入问题不只出现在 HTTP 节点上。凡是输出结构会变化的节点比如 Code、Merge、Transform 类节点都有可能改变下游能看到的字段。我的习惯是进入循环后先放一个 Set 节点把从这条数据开始就必须全程携带的关键字段复制一份并加上固定前缀比如send_email、send_name。后面即便数据流被接口响应覆盖我还能用类似{{ $json.send_name }}或从 Set 节点回引的方式把字段找回来。这种“先存档再处理”的思路在循环场景里特别好使。如果你不确定当前节点到底有什么字段最快的办法是直接看执行日志。在 n8n 的编辑界面里点击任意节点左侧的小圆点可以查看该节点这一步的输入输出数据。点开看一次比反复猜表达式要高效得多。4.3 嵌套循环怎么搭才不失控Loop Over Items 是可以嵌套使用的。比如外层循环遍历所有客户每个客户下面又有多个订单需要继续逐条处理这时可以在外层循环体内再放一个 Loop Over Items 节点让内层循环去遍历“当前客户的订单列表”。但嵌套循环的复杂度是成倍增长的。你在内层循环里引用数据时要格外小心内层节点能直接看到的往往是内层 Loop 节点送进来的订单数据如果你还想同时引用外层客户信息通常需要像 4.2 节说的那样在进入内层循环前先通过一个 Set 节点把外层客户 ID、邮箱等字段合并到订单数据里让内层循环的每个 item 都“自带上下文”。嵌套层数最好不要超过两层。超过两层之后执行日志的排查难度会非常大每一层是哪一轮出了问题都不容易看清。如果你的业务流程真的需要三层以上遍历我建议先把逻辑拆成多个工作流用子工作流Execute Workflow串联每层单独测试这样维护起来会轻松很多。4.4 循环结束后想汇总结果怎么办循环处理完之后最自然的收尾就是通过 done 输出接一个节点。但要注意done 分支上的节点并不会自动收到“所有循环处理结果的汇总列表”它只是收到一个“循环完成”的信号。想要汇总每次循环产生的数据有一个常用思路在循环体内的最后一个节点把该次处理结果写入一个外部存储比如追加到 Google Sheets 的行里、更新到数据库表中或者通过 HTTP 请求写入数据仓库循环结束后再用一个查询节点去读取这份汇总数据。如果不想引入外部存储也可以用 n8n 的 Code 节点在 done 分支后用$(Loop Over Items).all()这类表达式尝试收集循环节点的全部输出。但这类表达式需要结合你的 n8n 版本和数据流仔细验证不是在所有情况下都能拿到你期望的那个列表。所以我更推荐“边循环边落库”的方式它虽然多一次存储调用但数据可靠排查也方便。5. 常见问题排查与避坑记录5.1 高频问题速查表把我在实际使用中碰到过、以及社群里高频出现的问题整理成了一张速查表遇到对应现象可以直接对照问题现象可能原因排查与解决办法循环没有逐条执行像一次性全跑了Batch Size 配置比预期大或上游节点本来就只有一个聚合 item检查循环节点参数里的 Batch Size看看上游输出 item 数量循环完全没有执行上游输出的 items 数量为 0在上游节点执行结果里确认数据是否为空后续节点拿不到原始用户字段HTTP Request 或转换节点覆盖了输入 item用 Set 节点重新组装字段或开启“包含输入数据”选项循环内某一条报错整个工作流中断n8n 对执行失败的默认行为就是中断在上游尽量清洗数据用 IF 节点把可疑数据分流不要带病进循环done 分支没有触发循环内某节点执行失败导致工作流提前退出先修复循环内的报错再检查 done 分支是否接对了输出口外部接口报 429 限流错误请求频率超过接口限制Batch Size 调小或在循环中加 Wait 节点控制节奏工作流执行特别慢items 数量巨大每轮又有外部请求拆分批次执行考虑并发/队列或减少外部请求次数连续多次执行同一工作流后循环次数不对循环状态可能残留到了下一次执行检查节点参数里是否有 Reset 选项结合文档开启重置5.2 循环被中断时的定位思路任何批量任务最怕的不是出错而是出错后不知道错在哪。Batch Size 1 的时候定位问题还相对容易你只要看执行日志里最后一轮失败的那次迭代就能确定是哪一条数据引发了异常。但如果你一上来就把 Batch Size 调到 50某一条脏数据可能导致整轮 50 个请求全部失败定位粒度就粗了。我的建议是新流程先用 Batch Size 1 跑通确认逻辑稳定后再放大批次。即便放大批次循环体内的关键检查也不能少比如调用外部接口之前先把必填参数做一次校验。遇到 email 为空、user_id 不是数字这种情况与其让它在接口层报错不如提前用 IF 节点把这个 item 引导到一个“跳过并记录”的分支里保证整个循环继续推进。如果你确实需要“某一条失败但不要影响其他条继续处理”靠单个循环很难做到优雅。n8n 没有节点级的 try/catch社区里有人会用异常分支或者错误工作流来处理但这类方案往往要引入额外的状态记录复杂度不低。对大多数业务来说提前清洗数据远比事后补救更可靠。5.3 大批量循环时的性能与部署建议随着热词里出现 n8n 本地部署、企业级部署我想特别提醒一下当循环的数据量上来以后性能问题会逐渐暴露。如果只是几百条数据Loop Over Items 在默认配置下基本没什么压力。但如果一次要遍历几万条情况就不同了。n8n 会把每次迭代的执行记录和中间数据都保留下来几万条迭代的执行日志会占用大量存储和内存编辑界面也可能卡顿。这个时候更好的做法不是在单个工作流里硬跑而是考虑拆批用定时触发器或队列把几万条数据切成几百个批次每个批次独立执行一个较小的工作流
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门