本文介紹了輸入和輸出的基本知識,您可以參見本文樣本進行操作。
流程和步驟
通常流程的多個步驟之間需要傳遞資料。和函數式程式設計語言類似,FDL的步驟類似於函數,它接受輸入(Input),並返回輸出(Output),輸出會儲存在父步驟(調用者)的本地(Local)變數裡。其中,輸入和輸出的類型必須是JSON對象格式,本地變數的類型因步驟而異。例如任務步驟把調用Function Compute函數的返回結果作為本地變數,並行步驟把它所有分支的輸出(數組)作為本地變數。步驟的輸入、輸出和本地變數總大小不能超過32 KiB,否則會導致流程執行失敗。
如果一個步驟包含另一個步驟,則稱外層步驟為父步驟,被包含步驟為子步驟。最外層步驟的父步驟是流程。如果兩個步驟的父步驟相同,則這兩個步驟是同級步驟。
流程和步驟都有輸入、輸出和本地變數。他們的轉換關係如下:
- 步驟輸入映射(
inputMappings)將父步驟的輸入和本地變數映射為子步驟的輸入。 - 步驟輸出映射(
outputMappings)將當前步驟的輸入和本地變數映射為當前步驟的輸出。 - 流程輸入映射(
inputMappings)將使用者執行流程時的輸入映射為流程的輸入。 - 流程輸出映射(
outputMappings)將流程輸入和本地變數映射為流程的輸出。
一個父步驟的本地變數儲存了其所有子步驟輸出的合并,如果輸出中有同名索引值,則後執行步驟會覆蓋前執行步驟的結果。在大多數情況下,您不需要指定輸入和輸出映射,而使用預設的映射行為。他們的轉換關係如下:
- 在不指定輸入映射情況下,子步驟的輸入是其父步驟輸入和父步驟本地變數的合并(如果本地變數和輸入有同名索引值,則本地變數會覆蓋輸入)。
- 在不指定輸出映射情況下,除並行步驟和並行迴圈步驟外的其它步驟都會將本地變數作為輸出。
如果您想更好地控制輸入和輸出,則需要瞭解詳細的映射規則。
下面樣本流程的輸入輸出映射如圖所示。其中step1是step2和step3的父步驟。step1和step4是最外層步驟。
version: v1
type: flow
steps:
- type: parallel
name: step1
branches:
- steps:
- type: pass
name: step2
- steps:
- type: pass
name: step3
- type: pass
name: step4 
為了便於理解,這些映射可以用下面的代碼描述。
func flow(input0 Input) (output0 Output) {
local0 := {}
input1 := buildInput(step1InputMappings, input0, local0)
output1 := step1(input1)
save(local0, output1)
input4 := buildInput(step4InputMappings, input0, local0)
output4 := step4(input4)
save(local0, output4)
return buildOutput(flowOutputMappings, input0, local0)
}
func step1(input1 Input) (output1 Output) {
local10 := {}
input2 := buildInput(step2InputMappings, input1, local10)
output2 := step2(input2)
save(local10, output2)
local11 := {}
input3 := buildInput(step3InputMappings, input1, local11)
output3 := step3(input3)
save(local11, output3)
return buildOutput(step1OutputMappings, [local10, local11])
}
func step2(input2 Input) (output2 Output) {
}
func step3(input3 Input) (output3 Output) {
}
func step4(input4 Input) (output4 Output) {
} 在這個例子中,流程包含了兩個子步驟:step1和step4。step1是一個並行步驟,它包含step2和step3兩個子步驟。
- 系統在開始執行流程時,根據流程的輸入映射將
StartExecution輸入轉換為流程輸入(input0)。 - 在
flow開始時,其local0為空白。 - 系統根據
step1的輸入映射(step1InputMappings)來為它準備輸入input1,映射的源來自flow的輸入input0和本地變數local0。 - 調用
step1,傳入輸入input1,step1返回輸出output1。- 在
step1開始時,其local0為空白 。因為step1是一個並行步驟,所以每個分支都對應一個本地變數,從而避免並發訪問的問題。 - 系統根據
step2的輸入映射(step2InputMappings)來為它準備輸入input2,映射的源來自step1的輸入input1和本地變數local10。 - 調用
step2,傳入輸入input2,step2返回輸出output2。 - 系統將
step2的輸出儲存到step1的本地變數local10。 - 同樣的,系統調用
step3並將結果儲存在step1的本地變數local11。
- 在
- 系統將
step1的輸出儲存到flow的本地變數local0。 - 類似的,系統根據
step4的輸入映射來為它準備輸入input4,映射的源來自flow的輸入input0和本地變數local0。說明 這時的本地變數local0可能已經包含了step1的輸出,從而實現了step1和step4的資料傳遞。 - 調用
step4,傳入輸入input4,step4返回輸出output4。 - 系統將
step4的輸出儲存到flow的本地變數local0。 - 最後,系統根據流程的輸出映射將
local0轉換為流程輸出。
類型定義
輸入映射和輸出映射都是由target和source組成的數群組類型,其中source定義了參數來源,根據不同的映射取值不同,例如$input.key表示參數來自輸入input的$.key所對應的值,target定義了目標參數名稱。 當source以$開始表示該值通過JSON Path方式指定(可以通過這個工具調試JSON Path),系統會根據該路徑解析為具體值,否則認為該值是常量類型。
- 來源(Source)
來源支援使用常量作為
source值,可以使用數字(number)、字串(string)、布爾(boolean)、數組(array)、對象(object)或者null類型。下面樣本映射的source使用了不同類型的常量,其產生的輸出如下所示。
outputMappings: - target: int_key source: 1 - target: bool_key source: true - target: string_key source: abc - target: float_key source: 1.234 - target: null_key source: null - target: array1 source: [1, 2, 3] - target: array2 source: - 1 - 2 - 3 - target: object1 source: {a: b} - target: object2 source: a:{ "array1": [1, 2, 3], "array2": [1, 2, 3], "bool_key": true, "float_key": 1.234, "int_key": 1, "null_key": null, "object1": { "a": "b" }, "object2": { "a": "b" }, "string_key": "abc" } - 目標
目標只能是一個字串類型常量。
輸入映射
輸入映射將父步驟的輸入($input)、父步驟的本地變數($local)、或者常量轉換為子步驟的輸入。如果沒有指定輸入映射,父步驟的輸入和父步驟的本地變數合并後會被當做子步驟的輸入。如果父步驟的輸入和父步驟的本地變數中有相同名稱,則新的輸入中採用本地變數中的名或值。
inputMappings:
- target: key1
source: $input.key1
- target: key2
source: $local.key2
- target: key3
source: literal 輸入 $input | 本地變數 $local | 輸入映射 | 子步驟輸入 |
| | | |
| | 無 | |
| | 無 | |
輸出映射
輸出映射將當前步驟的輸入($input)、本地變數($local)、或者常量轉換為本地步驟的輸出。如果沒有指定輸出映射,對於選擇步驟和迴圈步驟,它們的本地變數會被當做其輸出,任務步驟會將具體任務執行結果作為輸出。由於並行(Parallel)和並行迴圈(ForEach)步驟的本地變數是數群組類型,所以您需要定義輸出映射將數群組轉換結果成JSON對象格式,預設不會輸出它們的本地變數。具體介紹可參見步驟描述。
outputMappings:
- target: key1
source: $input.key1
- target: key2
source: $local.key2
- target: key3
source: literal 輸入 $input | 本地變數 $local | 輸出映射 | 步驟輸出 |
| | | |
| | | |
| | 無 | |
輸出如何儲存到父步驟本地變數
子步驟的輸出($output)會被併入父步驟的本地變數。如果二者有重複名稱,則輸出中的名或值會覆蓋本地變數相應名或值。
輸出 $output | 父步驟本地變數 $local | 更改後父步驟本地變數 |
| | |
| | |