跳至主要內容

Workflow.foreach()

.foreach() 方法會建立迴圈,為陣列中的每個項目執行一個 step。它必定傳回包含每次反覆運算輸出的陣列,並保留原有次序。

使用範例
使用範例 的直接連結

workflow.foreach(step1, { concurrency: 2 })

參數
參數 的直接連結

step:

Step
在迴圈中執行的 step instance。上一個 step 必須傳回陣列類型。

opts?:

object
迴圈的可選設定。concurrency 選項控制可平行執行的反覆運算數目(預設值:1)
number

傳回值
傳回值 的直接連結

workflow:

Workflow
用於串連方法的 Workflow instance。輸出類型是由 step 輸出類型組成的陣列。

行為
行為 的直接連結

執行及等待
執行及等待 的直接連結

.foreach() 方法會先處理所有項目,然後才執行下一個 step。無論 concurrency 設定為何,只有在每次反覆運算均完成後,.foreach() 之後的 step 才會執行。使用 concurrency: 1(預設值)時,項目會依次處理。使用較高的 concurrency 時,項目會分批平行處理,但下一個 step 仍會等待所有批次完成。

如需為每個項目執行多個操作,請使用巢狀 Workflow 作為 step。這樣可將每個項目的所有操作組合在一起,亦比串連多個 .foreach() 呼叫更簡潔。範例請參閱 foreach 內的巢狀 Workflow

輸出結構
輸出結構 的直接連結

.foreach() 必定輸出陣列。輸出陣列中的每個元素,都對應輸入陣列中相同索引位置的元素經處理後所得的結果。

// Input: [{ value: 1 }, { value: 2 }, { value: 3 }]
// Step adds 10 to each value
// Output: [{ value: 11 }, { value: 12 }, { value: 13 }]

.foreach() 後使用 .then()
using-then-after-foreach 的直接連結

.foreach() 後串連 .then() 時,下一個 step 會接收整個輸出陣列作為輸入。你可以彙總或一併處理所有結果。

workflow
.foreach(processItemStep) // Output: array of processed items
.then(aggregateStep) // Input: the entire array
.commit()

.foreach() 後使用 .map()
using-map-after-foreach 的直接連結

在將陣列輸出傳遞至下一個 step 前,使用 .map() 轉換該陣列:

workflow
.foreach(processItemStep)
.map(async ({ inputData }) => ({
total: inputData.reduce((sum, item) => sum + item.value, 0),
count: inputData.length,
}))
.then(nextStep)
.commit()

串連多個 .foreach() 呼叫
chaining-multiple-foreach-calls 的直接連結

串連 .foreach() 呼叫時,每個呼叫都會處理上一個 step 所傳回的陣列:

workflow
.foreach(stepA) // If input is [a, b, c], output is [A, B, C]
.foreach(stepB) // Operates on [A, B, C], output is [A', B', C']
.commit()

如果 .foreach() 內的 step 傳回陣列,輸出便會成為陣列的陣列。使用 .map() 配合 .flat() 將其攤平:

workflow
.foreach(chunkStep) // Output: [[chunk1, chunk2], [chunk3, chunk4]]
.map(async ({ inputData }) => inputData.flat()) // Output: [chunk1, chunk2, chunk3, chunk4]
.foreach(embedStep)
.commit()

串流期間的進度事件
串流期間的進度事件 的直接連結

使用 run.stream() 時,foreach step 會在每次反覆運算完成後發出 workflow-step-progress 事件。這讓你無需等待整個 foreach 完成,便可實時追蹤進度。

const run = await workflow.createRun()
const stream = run.stream({ inputData })

for await (const chunk of stream) {
if (chunk.type === 'workflow-step-progress') {
console.log(`${chunk.payload.completedCount}/${chunk.payload.totalCount}`)
// e.g. "1/3", "2/3", "3/3"
}
}

每個進度事件的 payload 都包含:

id:

string
foreach step 的 step ID

completedCount:

number
到目前為止已完成的反覆運算數目

totalCount:

number
反覆運算總數

currentIndex:

number
剛完成的反覆運算索引

iterationStatus:

'success' | 'failed' | 'suspended'
剛完成的反覆運算狀態

iterationOutput?:

Record<string, any>
反覆運算的輸出(iterationStatus 為 'success' 時存在)

恢復單次反覆運算
恢復單次反覆運算 的直接連結

.foreach() 內的 step 暫停時,每次反覆運算會各自暫停。將 forEachIndex 傳遞至 run.resume(),即可使用各自的 resumeData,每次恢復一個反覆運算。如省略 forEachIndex,所有已暫停的反覆運算都會使用相同資料恢復。

await run.resume({
step: 'approve',
resumeData: { ok: true },
forEachIndex: 1,
})