Циклы
Итерация по данным и циклическая обработка в n8n
Автоматическая итерация
Заголовок раздела «Автоматическая итерация»По умолчанию n8n автоматически обрабатывает каждый item:
Нода выполнится 3 раза — по одному для каждого item.
Loop Over Items
Заголовок раздела «Loop Over Items»Явный цикл с контролем итерации.
Когда использовать
Заголовок раздела «Когда использовать»- Обработка с паузами (rate limiting)
- Batch processing
- Условная остановка цикла
- Отслеживание прогресса
Настройка
Заголовок раздела «Настройка»| Параметр | Описание |
|---|---|
| Batch Size | Items за одну итерацию |
| Options | Reset, Pause |
Пример: Rate-limited API
Заголовок раздела «Пример: Rate-limited API»- Loop Over Items: Batch Size = 1
- HTTP Request: API вызов
- Wait: 1 секунда
- Done: Подключить выход “done”
Split In Batches
Заголовок раздела «Split In Batches»Разбиение на пакеты для параллельной обработки.
Настройка
Заголовок раздела «Настройка»| Параметр | Описание |
|---|---|
| Batch Size | Размер пакета |
Паттерн обработки
Заголовок раздела «Паттерн обработки»// В Code после Split In Batchesconst batch = $input.all();
// Обработка пакетаconst results = await Promise.all( batch.map(item => processItem(item)));
return results;Рекурсивные workflow
Заголовок раздела «Рекурсивные workflow»Вызов workflow из самого себя для обработки иерархий.
Execute Workflow (Self)
Заголовок раздела «Execute Workflow (Self)»Пример: Обход дерева
Заголовок раздела «Пример: Обход дерева»// Входные данные{ "id": 1, "children": [ { "id": 2, "children": [] }, { "id": 3, "children": [ { "id": 4, "children": [] } ]} ]}Workflow:
- Получить текущий узел
- Обработать узел
- Для каждого child вызвать этот же workflow
- Собрать результаты
While-цикл через Loop
Заголовок раздела «While-цикл через Loop»Цикл с условием выхода:
Реализация
Заголовок раздела «Реализация»// В Code ноде внутри циклаconst currentItem = $input.first();const shouldContinue = currentItem.json.hasMore;
if (!shouldContinue) { // Завершить цикл return [];}
// Продолжитьreturn [currentItem];Pagination
Заголовок раздела «Pagination»Получение данных постранично.
Встроенная пагинация
Заголовок раздела «Встроенная пагинация»HTTP Request поддерживает автоматическую пагинацию:
| Параметр | Значение |
|---|---|
| Pagination Mode | Update a Parameter Each Request |
| Parameter | page |
| Start Value | 1 |
| Update | +1 |
Ручная пагинация
Заголовок раздела «Ручная пагинация»// В Code нодеconst response = $input.first().json;const currentPage = $('Set Page').first().json.page;
if (response.hasNextPage) { return [{ json: { page: currentPage + 1, data: response.data } }];}
// Пагинация завершенаreturn [{ json: { done: true, allData: response.data }}];Performance Tips
Заголовок раздела «Performance Tips»Batch вместо поэлементной обработки
Заголовок раздела «Batch вместо поэлементной обработки»// ❌ Медленноitems.forEach(async item => { await apiCall(item);});
// ✅ Быстроawait apiCall(items); // Если API поддерживает batchПараллельная обработка
Заголовок раздела «Параллельная обработка»Используйте Split In Batches с оптимальным размером:
- Маленькие batches: меньше памяти, больше overhead
- Большие batches: больше памяти, меньше overhead
- Оптимум: 50-100 items при batch API
Ограничение параллелизма
Заголовок раздела «Ограничение параллелизма»// В Code нодеconst CONCURRENT_LIMIT = 5;const items = $input.all();const results = [];
for (let i = 0; i < items.length; i += CONCURRENT_LIMIT) { const batch = items.slice(i, i + CONCURRENT_LIMIT); const batchResults = await Promise.all( batch.map(item => processItem(item)) ); results.push(...batchResults);}
return results.map(r => ({ json: r }));Паттерны
Заголовок раздела «Паттерны»Retry с экспоненциальным backoff
Заголовок раздела «Retry с экспоненциальным backoff»const maxRetries = 3;let attempt = $input.first().json.attempt || 0;
try { const result = await riskyOperation(); return [{ json: result }];} catch (error) { if (attempt < maxRetries) { // Продолжить цикл с увеличенным attempt return [{ json: { attempt: attempt + 1, waitTime: Math.pow(2, attempt) * 1000 } }]; } throw error;}Cursor-based пагинация
Заголовок раздела «Cursor-based пагинация»const response = $input.first().json;const cursor = response.nextCursor;
if (cursor) { return [{ json: { cursor, accumulatedData: [ ...($json.accumulatedData || []), ...response.data ] } }];}
// Все данные полученыreturn [{ json: { data: [...($json.accumulatedData || []), ...response.data] }}];Следующие шаги
Заголовок раздела «Следующие шаги»- Трансформация данных — преобразование
- Слияние данных — объединение потоков
- Code Node — программирование в n8n