【n8n教程】:掌握内置方法与变量,让您的工作流如虎添翼

n8n 作为一款强大的工作流自动化工具,提供了一套丰富的内置方法和变量,让您可以直接在工作流中处理数据、访问执行信息和管理工作流状态。无论您是初学者还是想提升自动化能力,这篇教程都能帮您快速上手。

本教程将深入浅出地介绍以下核心概念:

核心概念一:execution(执行信息)

什么是 execution?

execution 是 n8n 中一个非常重要的内置对象,它包含了当前工作流执行的所有关键信息。每当您的工作流运行时,n8n 都会自动创建一个 execution 对象,让您可以在代码节点中访问这些信息。

execution 的主要属性

1. execution.id - 获取执行 ID

每个工作流执行都有一个唯一的 ID。这对于追踪、日志记录或在其他系统中引用执行非常有用。

使用场景:

示例代码:


    
    
    
  // 在代码节点中获取执行 ID
const
 executionId = $execution.id;
console
.log(`当前执行 ID: ${executionId}`);

// 返回包含执行 ID 的数据

return
 [{
  json
: {
    executionId
: executionId,
    timestamp
: new Date().toISOString()
  }
}];

2. execution.resumeUrl - 获取恢复 URL

当您在工作流中使用 Wait(等待)节点并设置等待 webhook 回调时,execution.resumeUrl 提供一个 webhook URL,外部系统可以调用它来恢复暂停的工作流。

使用场景:

示例代码:


    
    
    
  // 获取恢复 URL 用于 webhook 回调
const
 resumeUrl = $execution.resumeUrl;

// 发送恢复 URL 到邮件或其他系统

return
 [{
  json
: {
    message
: '工作流已暂停,请访问下面的链接继续',
    resumeUrl
: resumeUrl,
    expiresIn
: '24 小时'
  }
}];

核心概念二:getWorkflowStaticData()(工作流静态数据)

什么是工作流静态数据?

getWorkflowStaticData() 让您可以在工作流中存储和检索持久化数据。这些数据在工作流执行完成后会被保存,下次执行时仍然可以访问。这对于记录状态信息非常有用。

重要提示:

两种类型的静态数据

1. 全局静态数据 - 整个工作流共享


    
    
    
  // 在代码节点中使用全局静态数据
const
 staticData = $workflow.getStaticData('global');

// 读取上次保存的值

const
 lastProcessedId = staticData.lastId || 0;
console
.log(`上次处理的 ID: ${lastProcessedId}`);

// 更新静态数据(工作流执行成功后自动保存)

staticData.lastId = 100;
staticData.lastUpdated = new Date().toISOString();

return
 [{
  json
: {
    message
: '静态数据已更新',
    lastId
: staticData.lastId,
    lastUpdated
: staticData.lastUpdated
  }
}];

2. 节点静态数据 - 仅当前节点使用


    
    
    
  // 获取当前节点的静态数据
const
 nodeStaticData = $workflow.getStaticData('node');

// 只有这个节点能访问和修改

nodeStaticData.localCounter = (nodeStaticData.localCounter || 0) + 1;

return
 [{
  json
: {
    nodeCounter
: nodeStaticData.localCounter
  }
}];

常见使用场景:

核心概念三:itemMatching()(项目匹配)

什么是 itemMatching?

itemMatching() 让您可以追踪数据项目在工作流中的来源。当数据经过多个节点转换后,您有时需要找到原始数据或中间步骤的数据。这个方法就是用来解决这个问题的。

理解项目链接:
每个项目都记录了它是如何生成的,从哪个上游节点来的。这形成了一条"链接",让您可以回溯项目的来源。

使用语法


    
    
    
  // 基本语法
const
 linkedItem = $("节点名称").itemMatching(当前项目的输入索引);

// 这会返回生成当前项目的上游节点的项目数据

实际例子:数据恢复

假设您有这样的工作流:

  1. 1. 数据源节点:获取完整的客户信息(包括 ID、名称、邮箱)
  2. 2. 编辑字段节点:只保留名称字段(简化数据)
  3. 3. 代码节点:需要恢复邮箱地址

    
    
    
  // 代码节点中的实现
const
 items = [];

for
 (let i = 0; i < $input.item.length; i++) {
  // 获取当前简化后的项目

  const
 simplifiedItem = $input.item(i);
  
  // 使用 itemMatching 获取原始项目

  const
 originalItem = $("数据源节点").itemMatching(i);
  
  // 从原始项目中恢复邮箱

  const
 restoredEmail = originalItem.json.email;
  
  items.push({
    json
: {
      name
: simplifiedItem.json.name,
      restoredEmail
: restoredEmail,
      source
: '已恢复邮箱'
    }
  });
}

return
 items;

核心概念四:(.all())(访问所有项目)

什么是 .all()?

.all() 方法让您可以访问节点输出的所有项目数据。这在您需要一次性处理所有数据而不是逐项处理时非常有用。

使用语法


    
    
    
  // 从当前节点获取所有项目
const
 allItems = $input.all();

// 从上一个节点获取所有项目

const
 previousNodeItems = $("上一个节点名称").all();

// 可选参数指定分支和运行索引

const
 itemsFromBranch = $("节点名称").all(branchIndex, runIndex);

实际使用示例

示例 1:批量数据处理


    
    
    
  // 获取所有项目
const
 allItems = $input.all();

// 计算所有项目的总和

let
 totalAmount = 0;
allItems.forEach(item => {
  totalAmount += item.json.amount;
});

return
 [{
  json
: {
    totalItems
: allItems.length,
    totalAmount
: totalAmount,
    averageAmount
: totalAmount / allItems.length
  }
}];

示例 2:数据验证


    
    
    
  // 检查所有项目是否有效
const
 allItems = $input.all();
const
 validItems = [];
const
 invalidItems = [];

allItems.forEach((item, index) => {
  if
 (item.json.email && item.json.email.includes('@')) {
    validItems.push(item);
  } else {
    invalidItems.push({
      index
: index,
      item
: item,
      error
: '无效的邮箱格式'
    });
  }
});

return
 [{
  json
: {
    validCount
: validItems.length,
    invalidCount
: invalidItems.length,
    validItems
: validItems,
    invalidItems
: invalidItems
  }
}];

核心概念五:vars(工作流变量)

什么是 vars?

vars 提供了访问在 n8n 实例中定义的用户变量。这些变量在企业版本和部分功能中可用,用于存储跨工作流共享的配置信息。

可用性:

使用语法


    
    
    
  // 访问变量
const
 apiKey = vars.MY_API_KEY;
const
 baseUrl = vars.BASE_URL;
const
 timeout = vars.REQUEST_TIMEOUT;

// 在代码中使用

return
 [{
  json
: {
    configuration
: {
      apiKey
: apiKey,
      baseUrl
: baseUrl,
      timeout
: parseInt(timeout)
    }
  }
}];

对比:vars vs $env

n8n 中有两种变量访问方式,了解它们的区别很重要:

特性vars$env
创建方式n8n UI 中创建系统环境变量或 .env 文件
访问方式vars.VARIABLE_NAME$env.VARIABLE_NAME
作用域环境特定实例级别配置
修改方式只读不能从工作流修改
可用版本企业版所有版本
用途工作流配置参数系统级配置、密钥

完整实战案例:智能客户数据处理工作流

现在让我们创建一个完整的工作流,综合运用上面学到的所有概念。这个工作流的目标是:

  1. 1. 从数据源获取客户信息
  2. 2. 记录处理进度到静态数据
  3. 3. 验证和转换数据
  4. 4. 生成处理报告

工作流 JSON 代码


    
    
    
  {
  "name"
: "智能客户数据处理工作流",
  "nodes"
: [
    {

      "parameters"
: {},
      "id"
: "uuid-1",
      "name"
: "手动触发",
      "type"
: "n8n-nodes-base.manualTrigger",
      "typeVersion"
: 1,
      "position"
: [250, 300]
    }
,
    {

      "parameters"
: {
        "assignments"
: {
          "assignments"
: [
            {

              "id"
: "1",
              "name"
: "customerData",
              "value"
: "=[\n  {\"id\": \"C001\", \"name\": \"张三\", \"email\": \"zhangsan@example.com\", \"amount\": 1500},\n  {\"id\": \"C002\", \"name\": \"李四\", \"email\": \"lisi@example.com\", \"amount\": 2500},\n  {\"id\": \"C003\", \"name\": \"王五\", \"email\": \"wangwu@example.com\", \"amount\": 1800}\n]",
              "type"
: "expression"
            }

          ]

        }

      }
,
      "id"
: "uuid-2",
      "name"
: "设置客户数据",
      "type"
: "n8n-nodes-base.set",
      "typeVersion"
: 3.4,
      "position"
: [450, 300]
    }
,
    {

      "parameters"
: {
        "mode"
: "runOnceForAllItems",
        "jsCode"
: "// 获取工作流静态数据\nconst staticData = $workflow.getStaticData('global');\n\n// 初始化处理计数\nif (!staticData.processedCount) {\n  staticData.processedCount = 0;\n}\nif (!staticData.startTime) {\n  staticData.startTime = new Date().toISOString();\n}\n\n// 获取所有客户数据\nconst allItems = $input.all();\nconst processedItems = [];\n\nlet totalAmount = 0;\nlet validCount = 0;\n\nallItems.forEach((item, index) => {\n  const customer = item.json.customerData[index];\n  \n  // 验证数据\n  const isValid = customer.email && customer.email.includes('@');\n  \n  if (isValid) {\n    validCount++;\n    totalAmount += customer.amount;\n    \n    processedItems.push({\n      json: {\n        id: customer.id,\n        name: customer.name,\n        email: customer.email,\n        amount: customer.amount,\n        status: 'valid',\n        processedAt: new Date().toISOString(),\n        executionId: $execution.id\n      }\n    });\n  } else {\n    processedItems.push({\n      json: {\n        id: customer.id,\n        name: customer.name,\n        email: customer.email,\n        status: 'invalid',\n        error: '邮箱格式不正确'\n      }\n    });\n  }\n});\n\n// 更新静态数据\nstaticData.processedCount += validCount;\nstaticData.lastProcessTime = new Date().toISOString();\nstaticData.lastTotalAmount = totalAmount;\n\n// 返回处理结果\nreturn processedItems.map(item => ({\n  json: {\n    ...item.json,\n    statisticsInfo: {\n      totalProcessed: allItems.length,\n      validCount: validCount,\n      totalAmount: totalAmount,\n      averageAmount: totalAmount / validCount,\n      cumulativeProcessed: staticData.processedCount\n    }\n  }\n}));"
      }
,
      "id"
: "uuid-3",
      "name"
: "处理并验证数据",
      "type"
: "n8n-nodes-base.code",
      "typeVersion"
: 2,
      "position"
: [650, 300]
    }
,
    {

      "parameters"
: {
        "mode"
: "runOnceForAllItems",
        "jsCode"
: "// 生成最终报告\nconst allItems = $input.all();\n\nconst validItems = allItems.filter(item => item.json.status === 'valid');\nconst invalidItems = allItems.filter(item => item.json.status === 'invalid');\n\nconst totalAmount = validItems.reduce((sum, item) => sum + item.json.amount, 0);\n\nreturn [{\n  json: {\n    reportTitle: '客户数据处理报告',\n    executionId: $execution.id,\n    timestamp: new Date().toISOString(),\n    summary: {\n      totalCustomers: allItems.length,\n      validCustomers: validItems.length,\n      invalidCustomers: invalidItems.length,\n      validationRate: `${((validItems.length / allItems.length) * 100).toFixed(2)}%`,\n      totalAmount: totalAmount,\n      averageAmount: (totalAmount / validItems.length).toFixed(2)\n    },\n    validCustomers: validItems.map(item => item.json),\n    invalidCustomers: invalidItems.map(item => ({\n      id: item.json.id,\n      name: item.json.name,\n      error: item.json.error\n    }))\n  }\n}];"
      }
,
      "id"
: "uuid-4",
      "name"
: "生成报告",
      "type"
: "n8n-nodes-base.code",
      "typeVersion"
: 2,
      "position"
: [850, 300]
    }

  ]
,
  "connections"
: {
    "手动触发"
: {\n      "main": [\n        [\n          {\n            "node": "设置客户数据",\n            "type": "main",\n            "index": 0\n          }\n        ]\n      ]\n    },\n    "设置客户数据": {\n      "main": [\n        [\n          {\n            "node": "处理并验证数据",\n            "type": "main",\n            "index": 0\n          }\n        ]\n      ]\n    },\n    "处理并验证数据": {\n      "main": [\n        [\n          {\n            "node": "生成报告",\n            "type": "main",\n            "index": 0\n          }\n        ]\n      ]\n    }\n  },\n  "active": false,\n  "settings": {\n    "executionOrder": "v1"\n  }\n}

工作流说明

节点 1 - 手动触发

节点 2 - 设置客户数据

节点 3 - 处理并验证数据

节点 4 - 生成报告

快速参考速查表

方法/变量语法用途示例
execution.id$execution.id获取执行 IDconst id = $execution.id
execution.resumeUrl$execution.resumeUrl获取 webhook 恢复链接用于 Wait 节点
getStaticData()$workflow.getStaticData('global')访问全局静态数据记录处理进度
itemMatching()$("节点名").itemMatching(index)获取链接的上游项目追踪数据来源
.all()$input.all()$("节点名").all()获取所有项目批量处理数据
varsvars.VARIABLE_NAME访问工作流变量const key = vars.API_KEY

初学者常见错误及解决方案

❌ 错误 1:在测试时期望保存静态数据


    
    
    
  // ❌ 错误做法
// 在测试工作流时试图保存和读取静态数据

const
 staticData = $workflow.getStaticData('global');
staticData.counter = 1; // 在测试时不会保存!

✅ 正确做法: 确保工作流是活动状态(activated),并通过触发节点或 webhook 执行,而不是在编辑器中测试。

❌ 错误 2:混淆 .all() 和逐项处理


    
    
    
  // ❌ 错误做法 - 如果有 100 个项目,代码会执行 100 次
item.json.count = 0; // 每次都重置为 0

✅ 正确做法: 使用 "mode": "runOnceForAllItems" 并用 .all() 获取所有项目:


    
    
    
  const allItems = $input.all();
const
 totalCount = allItems.length;

❌ 错误 3:找不到上游节点的数据


    
    
    
  // ❌ 错误做法 - 节点名称拼写错误或不存在
const
 data = $("前面的节点").itemMatching(0); // 找不到!

✅ 正确做法: 确保节点名称完全匹配(包括大小写):


    
    
    
  const data = $("上一个节点的确切名称").itemMatching(0);

推荐最佳实践

  1. 1. 记录执行信息 - 在处理关键数据时,总是记录 $execution.id 用于追踪
  2. 2. 使用静态数据进行状态管理 - 对于需要持久化的数据(如时间戳、计数器),使用 getWorkflowStaticData()
  3. 3. 验证数据有效性 - 在处理数据前使用循环和条件检查
  4. 4. 提供详细的错误信息 - 返回包含错误详情的对象,便于调试
  5. 5. 性能考虑 - 对大数据集使用 .all() 和一次性处理,避免逐项重复计算

总结

通过掌握这五个核心内置方法和变量,您已经拥有了构建高效 n8n 工作流的重要工具:


官方文档[1]
n8n系列教程[2]

引用链接

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