【n8n教程】:Execute Sub-workflow节点,让自动化流程模块化、可复用

如果说普通的n8n工作流是一条完整的自动化流水线,那么子工作流就是可以被反复使用的"模块"。本教程将带你从入门到精通,用Execute Sub-workflow节点构建灵活、高效的工作流系统。

为什么需要子工作流?

问题场景

想象你有一个订单处理系统,需要以下步骤:

  1. 1. 订单验证:检查订单是否有效
  2. 2. 计算税费:根据地区计算税费
  3. 3. 生成发票:创建发票文档
  4. 4. 发送邮件:通知客户和团队

如果没有子工作流,每个新的业务流程都需要重新实现"计算税费"和"发送邮件"。这样做的问题是:

子工作流的优势

使用子工作流后,你可以:

优势说明
代码复用将"计算税费"独立为一个子工作流,任何需要这个功能的工作流都可以调用
易于维护修改逻辑只需要在一个地方,所有调用者自动获得更新
清晰结构每个子工作流代表一个明确的业务功能,大工作流变得简洁易读
并行执行可以并行调用多个子工作流,提高效率
测试友好子工作流可以独立测试,降低调试难度
n8n Execute Sub-workflow 完整实施步骤
n8n Execute Sub-workflow 完整实施步骤

核心概念解析

什么是父工作流和子工作流?


    
    
    
  ┌──────────────────────────────────────────────┐
│          父工作流(Parent Workflow)          │
│                                              │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  │
│  │ 触发器   │→ │ 处理     │→ │ 执行子   │  │
│  │ Trigger  │  │ 节点     │  │ 工作流   │  │
│  └──────────┘  └──────────┘  └────┬─────┘  │
│                                    │       │
│         ┌────────────────────────┐ │       │
│         │    数据传入 →          │ │       │
│         │    结果返回 ←          │ │       │
│         │                        │ │       │
│         │    ┌──────────────┐   │ │       │
│         │    │ 子工作流     │   │ │       │
│         │    │(Sub-workflow)│   │ │       │
│         │    │              │   │ │       │
│         │    │ 1. 触发器    │   │─┘       │
│         │    │ 2. 处理逻辑  │   │        │
│         │    │ 3. 返回结果  │   │        │
│         │    └──────────────┘   │        │
│         └────────────────────────┘        │
│                                              │
└──────────────────────────────────────────────┘

关键点:

  1. 1. 父工作流:主要的自动化流程,包含一个或多个"执行子工作流"节点
  2. 2. 子工作流:独立的、可被重复调用的工作流,必须以"Execute Sub-workflow Trigger"节点开始
  3. 3. 数据流:父工作流→子工作流的输入节点→子工作流处理→最后一个节点的输出→返回给父工作流

Input Data Mode(输入数据模式)

子工作流的触发节点支持三种输入模式,选择哪种取决于你对数据的控制需求:

1️⃣ Define using fields below(定义具体字段)


    
    
    
  这种模式最常用,适合大多数场景。
你明确定义子工作流期望接收什么数据。

例如:订单处理子工作流需要:
- customerName (字符串)
- orderAmount (数字)
- shippingAddress (字符串)

优点

缺点

2️⃣ Define using JSON example(JSON示例)


    
    
    
  这种模式让你提供一个JSON样本来说明数据结构。
系统会自动识别字段和类型。

例如:
{
  "customer": {
    "name": "张三",
    "email": "zhangsan@example.com"
  },
  "amount": 1000
}

优点

缺点

3️⃣ Accept all data(接受所有数据)


    
    
    
  不做任何限制,子工作流接受父工作流发来的任何数据。
子工作流需要自己处理可能的数据不一致。

优点

缺点


实战:一步步构建订单处理系统

现在我们用一个真实案例学习如何使用Execute Sub-workflow。

场景:自动化处理客户订单

业务流程:

  1. 1. 客户通过网站表单提交订单
  2. 2. n8n接收订单数据
  3. 3. 调用"订单处理"子工作流进行数据计算(计算税费、总价等)
  4. 4. 返回处理结果
  5. 5. 发送确认邮件给客户

第一步:创建子工作流

1. 新建工作流

2. 添加触发节点

3. 配置输入数据

字段名类型显示名称
customerNameString客户名称
orderAmountNumber订单金额
shippingCountryString配送国家

4. 添加处理逻辑

在Set节点中,配置以下字段:


    
    
    
  字段1: customerName = {{$json.customerName}}
字段2: orderAmount = {{$json.orderAmount}}
字段3: taxRate = 0.1              // 税率10%
字段4: taxAmount = {{$json.orderAmount * 0.1}}
字段5: totalAmount = {{$json.orderAmount * 1.1}}
字段6: processedAt = {{new Date().toISOString()}}
字段7: shippingCountry = {{$json.shippingCountry}}

解释:

5. 保存子工作流

💡 重要:子工作流不需要激活,它只在被父工作流调用时执行。


第二步:创建父工作流

1. 新建父工作流

2. 添加触发器

3. 添加数据处理节点

配置以下字段:


    
    
    
  字段1: customerName = {{$json.customer_name}}
字段2: orderAmount = {{$json.amount}}
字段3: shippingCountry = {{$json.country}}

这里我们假设外部系统发来的数据字段名是customer_nameamount,需要转换成我们期望的customerNameorderAmount

4. 添加Execute Sub-workflow节点

5. 配置子工作流调用

在Execute Sub-workflow节点中:

6. 添加发送邮件操作

配置如下:


    
    
    
  To: {{$json.customerName}} 对应的邮箱字段
    或 hardcode 一个测试邮箱

Subject: 订单已收到 - {{$json.orderAmount}}

Body: 
  亲爱的 {{$json.customerName}},

  感谢您的订单!

  订单详情:
  - 金额:{{$json.orderAmount}}
  - 税费:{{$json.taxAmount}}
  - 总计:{{$json.totalAmount}}
  - 配送国家:{{$json.shippingCountry}}
  - 处理时间:{{$json.processedAt}}

  感谢!

7. 测试工作流

8. 使用Postman或curl发送测试数据


    
    
    
  curl -X POST "https://your-n8n-instance.com/webhook/orders" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_name": "张三",
    "amount": 100,
    "country": "中国"
  }'

9. 查看执行结果

10. 激活工作流


完整可执行工作流代码

子工作流JSON


    
    
    
  {
  "name"
: "处理订单数据",
  "active"
: true,
  "nodes"
: [
    {

      "parameters"
: {
        "inputDataMode"
: "defineBelow",
        "inputs"
: {
          "fields"
: [
            {

              "name"
: "customerName",
              "type"
: "string",
              "displayName"
: "客户名称"
            }
,
            {

              "name"
: "orderAmount",
              "type"
: "number",
              "displayName"
: "订单金额"
            }
,
            {

              "name"
: "shippingCountry",
              "type"
: "string",
              "displayName"
: "配送国家"
            }

          ]

        }

      }
,
      "id"
: "when-called",
      "name"
: "当被另一个工作流调用时",
      "type"
: "n8n-nodes-base.executeWorkflowTrigger",
      "typeVersion"
: 1,
      "position"
: [250, 300]
    }
,
    {

      "parameters"
: {
        "keepOnlySet"
: false,
        "values"
: {
          "customerName"
: "={{$json.customerName}}",
          "orderAmount"
: "={{$json.orderAmount}}",
          "shippingCountry"
: "={{$json.shippingCountry}}",
          "taxRate"
: 0.1,
          "taxAmount"
: "={{$json.orderAmount * 0.1}}",
          "totalAmount"
: "={{$json.orderAmount * 1.1}}",
          "processedAt"
: "={{new Date().toISOString()}}",
          "status"
: "processed"
        }

      }
,
      "id"
: "process-order",
      "name"
: "处理订单数据",
      "type"
: "n8n-nodes-base.set",
      "typeVersion"
: 3.2,
      "position"
: [450, 300]
    }

  ]
,
  "connections"
: {
    "当被另一个工作流调用时"
: {
      "main"
: [
        [

          {

            "node"
: "处理订单数据",
            "type"
: "main",
            "index"
: 0
          }

        ]

      ]

    }

  }

}

父工作流JSON


    
    
    
  {
  "name"
: "订单接收系统",
  "active"
: true,
  "nodes"
: [
    {

      "parameters"
: {
        "httpMethod"
: "POST",
        "path"
: "webhook/orders",
        "responseMode"
: "waitForWebhookCall",
        "options"
: {}
      }
,
      "id"
: "webhook-trigger",
      "name"
: "Webhook",
      "type"
: "n8n-nodes-base.webhook",
      "typeVersion"
: 2,
      "position"
: [250, 300]
    }
,
    {

      "parameters"
: {
        "keepOnlySet"
: false,
        "values"
: {
          "customerName"
: "={{$json.customer_name}}",
          "orderAmount"
: "={{$json.amount}}",
          "shippingCountry"
: "={{$json.country}}"
        }

      }
,
      "id"
: "extract-data",
      "name"
: "提取订单信息",
      "type"
: "n8n-nodes-base.set",
      "typeVersion"
: 3.2,
      "position"
: [450, 300]
    }
,
    {

      "parameters"
: {
        "source"
: "database",
        "workflowId"
: "your-subworkflow-id-here"
      }
,
      "id"
: "execute-sub",
      "name"
: "执行订单处理",
      "type"
: "n8n-nodes-base.executeWorkflow",
      "typeVersion"
: 1,
      "position"
: [650, 300]
    }
,
    {

      "parameters"
: {
        "toEmail"
: "customer@example.com",
        "subject"
: "=订单已收到 - {{$json.orderAmount}}",
        "htmlBody"
: "=<h2>订单确认</h2><p>客户:{{$json.customerName}}</p><p>订单金额:{{$json.orderAmount}}</p><p>税费:{{$json.taxAmount}}</p><p>总计:{{$json.totalAmount}}</p><p>配送地:{{$json.shippingCountry}}</p><p>处理时间:{{$json.processedAt}}</p>"
      }
,
      "id"
: "send-email",
      "name"
: "发送确认邮件",
      "type"
: "n8n-nodes-base.emailSend",
      "typeVersion"
: 1,
      "position"
: [850, 300]
    }

  ]
,
  "connections"
: {
    "webhook-trigger"
: {
      "main"
: [
        [

          {

            "node"
: "extract-data",
            "type"
: "main",
            "index"
: 0
          }

        ]

      ]

    }
,
    "extract-data"
: {
      "main"
: [
        [

          {

            "node"
: "execute-sub",
            "type"
: "main",
            "index"
: 0
          }

        ]

      ]

    }
,
    "execute-sub"
: {
      "main"
: [
        [

          {

            "node"
: "send-email",
            "type"
: "main",
            "index"
: 0
          }

        ]

      ]

    }

  }

}

使用说明:

  1. 1. 复制上面的JSON代码
  2. 2. 在n8n中,点击"..."菜单 → "Import from File"或"Import from URL"
  3. 3. 粘贴JSON代码
  4. 4. 根据你的需求修改参数(邮箱、工作流ID等)
  5. 5. 保存并激活

常见问题解答

❓ 我如何知道子工作流的ID?

❓ 可以一次调用多个子工作流吗?

可以。在父工作流中添加多个Execute Sub-workflow节点,它们会按顺序执行。如果要并行执行,可以从同一个上游节点连接到多个子工作流节点。

❓ 子工作流出错会怎样?

如果子工作流有错误,整个父工作流会停止执行。解决办法:

❓ 子工作流可以调用另一个子工作流吗?

可以!这叫"嵌套子工作流"。n8n支持多层嵌套,但避免循环调用(A调用B,B调用A)。

❓ 如何调试子工作流?

  1. 1. 在子工作流中点击"Execute Workflow"测试
  2. 2. 在子工作流设置中启用"Save successful production executions"
  3. 3. 查看"Executions"标签的日志

❓ 子工作流可以有不同的触发器吗?

不可以。子工作流必须以"Execute Sub-workflow Trigger"节点开始。如果你想响应其他事件(如定时任务),应该在独立的工作流中实现。


进阶技巧

1. 条件调用子工作流

使用If节点来决定是否调用子工作流:


    
    
    
  如果 orderAmount > 1000
  → 调用"高价订单处理"子工作流
否则
  → 调用"普通订单处理"子工作流

2. 批量调用子工作流

使用"Loop"节点逐个处理数组中的每个元素,每次都调用子工作流:


    
    
    
  输入数据:[订单1, 订单2, 订单3]
Loop中:
  - 逐个提取订单
  - 每次调用子工作流处理
  - 收集所有结果

3. 错误处理

在Execute Sub-workflow节点的错误输出路径上添加处理:


    
    
    
  Execute Sub-workflow
  ├─ 主输出 → 继续正常流程
  └─ 错误输出 → 发送告警邮件 → 记录日志

4. 动态选择子工作流

使用"Switch"节点根据条件选择不同的子工作流:


    
    
    
  根据 processType 字段:
  case "validation" → 调用验证子工作流
  case "calculation" → 调用计算子工作流
  case "notification" → 调用通知子工作流

性能优化建议

  1. 1. 避免过深的嵌套:超过3层的嵌套会影响性能
  2. 2. 使用"Wait for Sub-Workflow Completion":根据需求选择是否等待
  3. 3. 模块化粒度:不要让子工作流做太多事情
  4. 4. 监控执行时间:定期检查子工作流的平均执行时间
  5. 5. 缓存结果:如果数据不经常变化,考虑缓存处理结果

总结

通过Execute Sub-workflow节点,你可以:

✅ 将复杂的自动化流程分解为可管理的模块
✅ 提高代码复用率和维护效率
✅ 构建更清晰、更易理解的工作流架构
✅ 实现灵活的错误处理和条件分支


引用链接

[1] 官方文档: https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.executeworkflow/
[2] n8n系列教程: https://www.undsky.com/blog/?category=n8n%E6%95%99%E7%A8%8B#