
工作原理
该工作流是一个关于 n8n 中Code node的实践教程,通过一个简单的数据处理任务,涵盖了基础与进阶概念。
- 提供示例数据:工作流以一个用户样本列表开始。
- 逐项处理(
Run Once for Each Item
) :第一个代码节点遍历每个用户来计算其fullName
和age
。这展示了使用$input.item.json
进行逐项数据操作的基础方法。 - 获取外部数据(高级) :第二个代码节点演示了更高级的功能。针对每个用户,它使用内置的
this.helpers.httpRequest
函数调用外部 API(genderize.io),通过预测性别来丰富数据。 - 批量处理所有项目(
Run Once for All Items
) :第三个代码节点接收完整增强后的用户列表,仅运行一次。它使用$items()
访问整个列表并计算averageAge
,最终返回一个汇总项。 - 创建二进制文件 :最终的代码节点再次获取完整丰富的用户列表,并创建一个二进制 CSV 文件,展示如何在 JavaScript 中使用二进制数据
Buffer
。
设置步骤
▶️ STARTING POINT: Sample Data
这些节点为教程准备数据。
1. Sample Data
:创建一个用户列表。你可以在这里自由修改数值进行实验!2. Split Out Users
:将列表拆分成多个 items,每个用户一个。这样做是为了让下一个 Code 节点能够逐一处理它们。


⚙️ LESSON 1: Processing Each Item
此节点处于 "Run Once for Each Item" 模式。它会针对每个用户执行一次。
目标: 丰富每个用户的数据。
关键概念:
$input.item.json
:访问当前正在处理的 item 的数据。return { ... }
:返回一个对象,作为该 item 的新输出。...user
技巧可以保留原始数据。
运行 workflow 并查看此节点的输出:你会看到多个 items,每个都新增了 fullName
和 age
。

js
// This code runs for EACH user individually.
// 1. Get the data for the current item
const user = $input.item.json;
// 2. Perform operations
const fullName = `${user.firstName} ${user.lastName}`;
const birthDate = new Date(user.birthDate);
const ageDiffMs = Date.now() - birthDate.getTime();
const ageDate = new Date(ageDiffMs);
const age = Math.abs(ageDate.getUTCFullYear() - 1970);
console.log(`Processing user: ${fullName}, Age: ${age}`);
// 3. Return the new data, keeping the original fields
return {
...user, // This keeps the original data (firstName, lastName, etc.)
fullName: fullName,
age: age
};
🚀 LESSON 2: Using Helpers
此节点同样会针对每个 item 运行,但演示了一个强大且进阶的功能。
目标: 通过在代码中调用外部 API 来丰富数据。
关键概念:
this.helpers.httpRequest
:一个内置函数,可直接发起 API 调用。非常适合处理动态 URL,或者在调用前后需要加入逻辑的情况。await
:这里使用它是因为 API 调用是一个 异步 操作。
查看输出:每个用户现在都有了从网络获取的 gender
数据!

js
// ADVANCED: This code calls an external API for each user.
// 1. Get the data for the current item
const user = $input.item.json;
// 2. Use a helper function to make an HTTP request
// 根据名字来猜测性别。
const url = `https://api.genderize.io?name=${user.firstName}`;
console.log(`Fetching external data for ${user.firstName} from ${url}`)
// this.helpers.httpRequest 是一个强大的内置函数。
// 我们使用 await,因为这是一个异步操作。
const response = await this.helpers.httpRequest({ url: url, json: true });
// 3. 返回原始数据与新的 API 数据的合并结果
return {
...user, // Keep all existing data (fullName, age, etc.)
gender: response.gender,
genderProbability: response.probability
};
⚙️ LESSON 3: Processing All Items at Once
此节点处于 "Run Once for All Items" 模式。它只运行一次,并能同时访问所有 items。
目标: 聚合数据以生成汇总信息。
关键概念:
$items()
:返回一个包含上一个节点所有 items 的 数组。return [ { json: { ... } } ]
:返回一个数组,其中包含一个带有最终结果的新 item。
查看此节点的输出:只有一个 item,其中包含用户总数和他们的平均年龄。

js
// This code runs only ONCE for ALL users.
// 1. Get all items from the previous node
const allUsers = $items();
// 2. Perform an aggregation
const totalAge = allUsers.reduce((sum, item) => {
return sum + item.json.age;
}, 0);
const userCount = allUsers.length;
const averageAge = totalAge / userCount;
console.log(`Calculated average age for ${userCount} users.`);
// 3. Return a single new item with the result
return [
{
json: {
totalUsers: userCount,
averageAge: parseFloat(averageAge.toFixed(2)) // Format to 2 decimal places
}
}
];
📄 LESSON 4: Creating Files
目标: 聚合所有 items 并生成一个二进制文件(此处示例为 CSV)。 模式: Run Once for All Items
关键概念:
$("4. Fetch External Data (Advanced)").all()
:获取第 4 步中的所有 items 数组。this.helpers.prepareBinaryData
:将原始数据(如文本字符串)转换为 n8n 可用的二进制文件。Buffer
:JavaScript 中处理二进制数据的标准方式。

js
// LESSON 4 (EXPERT): Creating a binary file.
// This node runs only ONCE for ALL items.
// 1. Get all items from the previous node
const allUsers = $("4. Fetch External Data (Advanced)").all();
// 2. Create a CSV string from the data
let csvContent = "FullName,Age,GenderGuess,ProcessedBy\n"; // CSV Header
for (const item of allUsers) {
const user = item.json;
const row = `"${user.fullName}",${user.age},${user.gender},n8n`;
csvContent += row + "\n";
}
// 3. Use a helper to create a binary file from the string
const binaryData = await this.helpers.prepareBinaryData(Buffer.from(csvContent), 'user_report.csv');
// 4. Return a new item containing the binary data
return [
{
json: {
reportGenerated: new Date().toISOString(),
userCount: allUsers.length
},
binary: {
'report': binaryData
}
}
];
最后
- n8n基础知识的学习就告一段落了,接下来会有一些高级的实践。
- 学习资料推荐
- 原文:点击打开
- 本文全部代码
json
{
"name": "6、n8n 代码节点(JavaScript)",
"nodes": [
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "38ce3db6-ce1d-4091-9645-39e674ad1782",
"name": "users",
"type": "array",
"value": "=[{\"firstName\":\"Alice\",\"lastName\":\"Smith\",\"birthDate\":\"1990-05-15\"},{\"firstName\":\"Bob\",\"lastName\":\"Jones\",\"birthDate\":\"1985-11-22\"},{\"firstName\":\"Charlie\",\"lastName\":\"Brown\",\"birthDate\":\"2001-02-10\"}, {\"firstName\":\"Alex\",\"lastName\":\"Garcia\",\"birthDate\":\"1995-07-30\"}]"
}
]
},
"options": {}
},
"id": "92c04b23-66f8-483d-b70f-cecf0ee51e85",
"name": "1. Sample Data",
"type": "n8n-nodes-base.set",
"position": [
-240,
208
],
"typeVersion": 3.4
},
{
"parameters": {
"fieldToSplitOut": "users",
"options": {}
},
"id": "03127769-8716-4907-af60-56906d9eecdb",
"name": "2. Split Out Users",
"type": "n8n-nodes-base.splitOut",
"position": [
-16,
208
],
"typeVersion": 1
},
{
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// This code runs for EACH user individually.\n\n// 1. Get the data for the current item\nconst user = $input.item.json;\n\n// 2. Perform operations\nconst fullName = `${user.firstName} ${user.lastName}`;\n\nconst birthDate = new Date(user.birthDate);\nconst ageDiffMs = Date.now() - birthDate.getTime();\nconst ageDate = new Date(ageDiffMs);\nconst age = Math.abs(ageDate.getUTCFullYear() - 1970);\n\nconsole.log(`Processing user: ${fullName}, Age: ${age}`);\n\n// 3. Return the new data, keeping the original fields\nreturn {\n ...user, // This keeps the original data (firstName, lastName, etc.)\n fullName: fullName,\n age: age\n};"
},
"id": "c425e7f1-f0ac-4a28-8881-14a3305617d3",
"name": "3. Process Each User",
"type": "n8n-nodes-base.code",
"position": [
304,
208
],
"typeVersion": 2
},
{
"parameters": {
"jsCode": "// This code runs only ONCE for ALL users.\n\n// 1. Get all items from the previous node\nconst allUsers = $items();\n\n// 2. Perform an aggregation\nconst totalAge = allUsers.reduce((sum, item) => {\n return sum + item.json.age;\n}, 0);\n\nconst userCount = allUsers.length;\nconst averageAge = totalAge / userCount;\n\nconsole.log(`Calculated average age for ${userCount} users.`);\n\n// 3. Return a single new item with the result\nreturn [\n {\n json: {\n totalUsers: userCount,\n averageAge: parseFloat(averageAge.toFixed(2)) // Format to 2 decimal places\n }\n }\n];"
},
"id": "d766b8d3-349a-484b-ab1b-25e980b459ee",
"name": "5. Calculate Average Age",
"type": "n8n-nodes-base.code",
"position": [
1104,
208
],
"typeVersion": 2
},
{
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// ADVANCED: This code calls an external API for each user.\n\n// 1. Get the data for the current item\nconst user = $input.item.json;\n\n// 2. Use a helper function to make an HTTP request\n// 根据名字来猜测性别。\nconst url = `https://api.genderize.io?name=${user.firstName}`;\n\nconsole.log(`Fetching external data for ${user.firstName} from ${url}`)\n\n// this.helpers.httpRequest 是一个强大的内置函数。\n// 我们使用 await,因为这是一个异步操作。\nconst response = await this.helpers.httpRequest({ url: url, json: true });\n\n// 3. 返回原始数据与新的 API 数据的合并结果\nreturn {\n ...user, // Keep all existing data (fullName, age, etc.)\n gender: response.gender,\n genderProbability: response.probability\n};"
},
"id": "74690167-680d-42ce-94f1-50eac60f5853",
"name": "4. Fetch External Data (Advanced)",
"type": "n8n-nodes-base.code",
"position": [
704,
208
],
"typeVersion": 2
},
{
"parameters": {
"content": "#### ▶️ STARTING POINT: Sample Data\n\n这些节点为教程准备数据。\n\n1. **`1. Sample Data`**:创建一个用户列表。你可以在这里自由修改数值进行实验!\n2. **`2. Split Out Users`**:将列表拆分成多个 items,每个用户一个。这样做是为了让下一个 Code 节点能够逐一处理它们。",
"height": 420,
"width": 440,
"color": 5
},
"id": "134ae4a5-1264-48ad-afae-d6333be9f2a6",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-304,
-32
],
"typeVersion": 1
},
{
"parameters": {
"content": "#### ⚙️ LESSON 1: Processing Each Item\n\n此节点处于 **\"Run Once for Each Item\"** 模式。它会针对每个用户执行一次。\n\n**目标:** 丰富每个用户的数据。\n\n**关键概念:**\n\n* `$input.item.json`:访问当前正在处理的 item 的数据。\n* `return { ... }`:返回一个对象,作为该 item 的新输出。`...user` 技巧可以保留原始数据。\n\n运行 workflow 并查看此节点的输出:你会看到多个 items,每个都新增了 `fullName` 和 `age`。",
"height": 580,
"width": 380,
"color": 7
},
"id": "2c17a395-08f2-4ea2-90b8-8ca1824080d0",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
160,
-192
],
"typeVersion": 1
},
{
"parameters": {
"content": "#### 🚀 ADVANCED LESSON 2: Using Helpers\n\n此节点同样会针对每个 item 运行,但演示了一个强大且进阶的功能。\n\n**目标:** 通过在代码中调用外部 API 来丰富数据。\n\n**关键概念:**\n\n* `this.helpers.httpRequest`:一个内置函数,可直接发起 API 调用。非常适合处理动态 URL,或者在调用前后需要加入逻辑的情况。\n* `await`:这里使用它是因为 API 调用是一个 *异步* 操作。\n\n查看输出:每个用户现在都有了从网络获取的 `gender` 数据!\n",
"height": 600,
"width": 380,
"color": 6
},
"id": "af1478ac-3a95-4543-957f-95a6b0755962",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
560,
-208
],
"typeVersion": 1
},
{
"parameters": {
"content": "#### ⚙️ LESSON 3: Processing All Items at Once\n\n此节点处于 **\"Run Once for All Items\"** 模式。它只运行一次,并能同时访问所有 items。\n\n**目标:** 聚合数据以生成汇总信息。\n\n**关键概念:**\n\n* `$items()`:返回一个包含上一个节点所有 items 的 **数组**。\n* `return [ { json: { ... } } ]`:返回一个数组,其中包含一个带有最终结果的新 item。\n\n查看此节点的输出:只有一个 item,其中包含用户总数和他们的平均年龄。\n",
"height": 580,
"width": 380,
"color": 7
},
"id": "c71f067c-8286-48bc-be1c-b2267d80980b",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
960,
-192
],
"typeVersion": 1
},
{
"parameters": {
"jsCode": "// LESSON 4 (EXPERT): Creating a binary file.\n\n// This node runs only ONCE for ALL items.\n\n// 1. Get all items from the previous node\nconst allUsers = $(\"4. Fetch External Data (Advanced)\").all();\n\n// 2. Create a CSV string from the data\nlet csvContent = \"FullName,Age,GenderGuess,ProcessedBy\\n\"; // CSV Header\n\nfor (const item of allUsers) {\n const user = item.json;\n const row = `\"${user.fullName}\",${user.age},${user.gender},n8n`;\n csvContent += row + \"\\n\";\n}\n\n// 3. Use a helper to create a binary file from the string\nconst binaryData = await this.helpers.prepareBinaryData(Buffer.from(csvContent), 'user_report.csv');\n\n// 4. Return a new item containing the binary data\nreturn [\n {\n json: {\n reportGenerated: new Date().toISOString(),\n userCount: allUsers.length\n },\n binary: {\n 'report': binaryData\n }\n }\n];"
},
"id": "8d4b3c1b-d662-47ab-95ce-8c580f460424",
"name": "6. Create a Binary File (Expert)",
"type": "n8n-nodes-base.code",
"position": [
1504,
208
],
"typeVersion": 2
},
{
"parameters": {
"content": "#### 📄 EXPERT LESSON 4: Creating Files\n\n**目标:** 聚合所有 items 并生成一个二进制文件(此处示例为 CSV)。\n**模式:** `Run Once for All Items`\n\n**关键概念:**\n\n* `$(\"4. Fetch External Data (Advanced)\").all()`:获取第 4 步中的所有 items 数组。\n* `this.helpers.prepareBinaryData`:将原始数据(如文本字符串)转换为 n8n 可用的二进制文件。\n* `Buffer`:JavaScript 中处理二进制数据的标准方式。\n",
"height": 580,
"width": 380,
"color": 3
},
"id": "c487b09b-ee2a-40be-ba4d-6f63f7564022",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1360,
-192
],
"typeVersion": 1
},
{
"parameters": {},
"id": "c6d72fe5-c323-4d60-b65b-cdb67ab7e07a",
"name": "Start Tutorial",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-528,
208
],
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"1. Sample Data": {
"main": [
[
{
"node": "2. Split Out Users",
"type": "main",
"index": 0
}
]
]
},
"Start Tutorial": {
"main": [
[
{
"node": "1. Sample Data",
"type": "main",
"index": 0
}
]
]
},
"2. Split Out Users": {
"main": [
[
{
"node": "3. Process Each User",
"type": "main",
"index": 0
}
]
]
},
"3. Process Each User": {
"main": [
[
{
"node": "4. Fetch External Data (Advanced)",
"type": "main",
"index": 0
}
]
]
},
"5. Calculate Average Age": {
"main": [
[
{
"node": "6. Create a Binary File (Expert)",
"type": "main",
"index": 0
}
]
]
},
"4. Fetch External Data (Advanced)": {
"main": [
[
{
"node": "5. Calculate Average Age",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "25462711-c86b-4066-9a1d-0c20f8231738",
"meta": {
"instanceId": "54c9e2e31753f3c874da48cdbf9552e23a88fbc2e067ac67b23af8418a890097"
},
"id": "oObgugBmC9LTnAb8",
"tags": []
}