

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 Lambda 函數在 Step Functions 中繼續新的執行
<a name="tutorial-use-lambda-cont-exec"></a>

**提示**  
下列方法使用 Lambda 函數來啟動新的工作流程執行。**建議使用** Step Functions 任務狀態來啟動新的工作流程執行。請參閱下列教學課程：**[使用 Step Functions API 繼續長時間執行的工作流程 （建議）](tutorial-continue-new.md)**。

您可以建立使用 Lambda 函數在目前執行終止之前啟動新執行的狀態機器。透過這種在新執行中持續工作的方法，您可以將大型任務分解為較小的工作流程，或無限期地執行工作流程。

本教學課程以使用外部 Lambda 函數修改工作流程的概念為基礎，已在[在 Step Functions 中使用 Lambda 函數反覆運算迴圈](tutorial-create-iterate-pattern-section.md)教學課程中示範。您可以使用相同的 Lambda 函數 (`Iterator`) 重複迴圈特定次數。此外，您可以建立另一個 Lambda 函數來啟動工作流程的新執行，並在每次啟動新的執行時減少計數。透過設定輸入中的執行次數，此狀態機器會結束並重新啟動指定次數的執行。

您將建立的狀態機器會實作下列狀態。


| State | 用途 | 
| --- | --- | 
| `ConfigureCount` |  一種`Pass`狀態`count`，可設定 `Iterator` Lambda 函數用來執行工作反覆運算的 `index`、 和 `step`值。  | 
|  `Iterator`  |  參考 `Iterator` Lambda 函數`Task`的狀態。  | 
| `IsCountReached` | Choice 使用Iterator函數的布林值來決定狀態機器是否應繼續範例工作，或移至 ShouldRestart 狀態的狀態。 | 
| `ExampleWork` | 代表在實際實作中執行工作之Task狀態Pass的狀態。 | 
| `ShouldRestart` | 使用 executionCount值來決定是否應結束一個執行並開始另一個執行，或直接結束Choice的狀態。 | 
| `Restart` | Task 使用 Lambda 函數啟動狀態機器新執行的狀態。如同 Iterator 函數，此函數也會減少計數。Restart 狀態會將計數的遞減值傳遞給新執行的輸入。 | 

## 先決條件
<a name="tutorial-continue-new-prereq"></a>

開始之前，請先完成[建立使用 Lambda 的 Step Functions 狀態機器](tutorial-creating-lambda-state-machine.md)教學課程，以確保您熟悉同時使用 Lambda 和 Step Functions。

## 步驟 1：建立 Lambda 函數以重複計數
<a name="tutorial-continue-new-step-1"></a>

**注意**  
如果您已完成[在 Step Functions 中使用 Lambda 函數反覆運算迴圈](tutorial-create-iterate-pattern-section.md)教學課程，您可以略過此步驟，並使用該 Lambda 函數。

本節和[在 Step Functions 中使用 Lambda 函數反覆運算迴圈](tutorial-create-iterate-pattern-section.md)教學說明如何使用 Lambda 函數來追蹤計數，例如，狀態機器中迴圈的反覆次數。

 下列 Lambda 函數會接收 `count`、 `index`和 的輸入值`step`。它會傳回包含更新 `index` 和名為 `continue` 布林值的這些值。`true` 如果 `index` 小於 ，Lambda 函數會`continue`設定為 `count`。

您的狀態機器實作 `Choice` 狀態，然後執行一些應用程式邏輯，如果 `continue` 是 `true`，或移至 `ShouldRestart` (如果 `continue` 是 `false`)。

### 建立疊代 Lambda 函數
<a name="tutorial-continue-new-create-lambda-function"></a>

1. 開啟 [Lambda 主控台](https://console.aws.amazon.com/lambda/home)，然後選擇 **Create function (建立函數)**。

1. 在 **Create function (建立函數)** 頁面上，選擇 **Author from scratch (從頭開始撰寫)**。

1. 在**基本資訊**區段中，設定您的 Lambda 函數，如下所示：

   1. 針對**函數名稱**，請輸入 `Iterator`。

   1. 針對 **執行時間**，請選擇 **Node.js 16.x**。

   1. 保留頁面上的所有預設選擇，然後選擇**建立函數**。

      建立 Lambda 函數時，請在頁面右上角記下其 Amazon Resource Name (ARN)，例如：

      ```
      arn:aws:lambda:region:123456789012:function:Iterator
      ```

1. 將 Lambda 函數的下列程式碼複製到 Lambda 主控台中***迭代器***頁面的**程式碼來源**區段。

   ```
   exports.handler = function iterator (event, context, callback) {
     let index = event.iterator.index;
     let step = event.iterator.step;
     let count = event.iterator.count;
    
     index = index + step;
    
     callback(null, {
       index,
       step,
       count,
       continue: index < count
     })
   }
   ```

   此程式碼接受輸入值為 `count`、`index` 和 `step`。這會將 `step` 的值增加 `index`，並傳回這些值及布林值 `continue`。如果 `index` 低於 `count`，則 `continue` 的值為 `true`。

1. 選擇**部署**以部署程式碼。

### 測試疊代 Lambda 函數
<a name="tutorial-continue-new-step-1-test"></a>

若要查看您的 `Iterate` 函數運作狀況，請使用數值來執行該函數。您可以為 Lambda 函數提供輸入值，以模擬反覆運算，以查看使用特定輸入值取得的輸出。

#### 測試 Lambda 函數
<a name="tutorial-continue-new-test-lambda-function"></a>

1. 在**設定測試事件**對話方塊中，選擇**建立新的測試事件**，然後`TestIterator`輸入**事件名稱**。

1. 將範例資料取代為以下內容。

   ```
   {
     "Comment": "Test my Iterator function",
     "iterator": {
       "count": 10,
       "index": 5,
       "step": 1
     }
   }
   ```

   這些值會模擬反覆運算期間來自狀態機器的內容。Lambda 函數會遞增索引，並傳回`continue`為 `true`。當索引未低於 `count`，就會以 `false` 的形式傳回 `continue`。對於此測試，索引已經增加到 `5`。結果應該將 `index` 增加到 `6` 和將 `continue` 設定為 `true`。

1. 選擇**建立**。

1. 在 Lambda 主控台的***迭代器***頁面上，確定已列出 **TestIterator**，然後選擇**測試**。

   測試結果會顯示在頁面頂端。選擇 **Details (詳細資訊)** 並檢閱結果。

   ```
   {
     "index": 6,
     "step": 1,
     "count": 10,
     "continue": true
   }
   ```
**注意**  
如果您將此測試的 `index` 設定為 `9`，則 `index` 會增加至 `10`，且 `continue` 為 `false`。

## 步驟 2：建立重新啟動 Lambda 函數以啟動新的 Step Functions 執行
<a name="tutorial-continue-new-step-3"></a>

1. 開啟 [Lambda 主控台](https://console.aws.amazon.com/lambda/home)，然後選擇 **Create function (建立函數)**。

1. 在 **Create function (建立函數)** 頁面上，選擇 **Author from scratch (從頭開始撰寫)**。

1. 在**基本資訊**區段中，設定您的 Lambda 函數，如下所示：

   1. 針對**函數名稱**，請輸入 `Restart`。

   1. 針對 **執行時間**，請選擇 **Node.js 16.x**。

1. 保留頁面上的所有預設選擇，然後選擇**建立函數**。

   建立 Lambda 函數時，請在頁面右上角記下其 Amazon Resource Name (ARN)，例如：

   ```
   arn:aws:lambda:region:123456789012:function:Iterator
   ```

1. 將 Lambda 函數的下列程式碼複製到 Lambda 主控台***重新啟動***頁面的**程式碼來源**區段。

   下列程式碼會減少執行數量的計數，並啟動狀態機器的新執行，包括遞減數值。

   ```
   var aws = require('aws-sdk');
   var sfn = new aws.StepFunctions();
   
   exports.restart = function(event, context, callback) {
   
     let StateMachineArn = event.restart.StateMachineArn;
     event.restart.executionCount -= 1;
     event = JSON.stringify(event);
   
     let params = {
         input: event,
         stateMachineArn: StateMachineArn
     };
   
     sfn.startExecution(params, function(err, data) {
         if (err) callback(err);
         else callback(null,event);
     });
   
   }
   ```

1. 選擇**部署**以部署程式碼。

## 步驟 3：建立狀態機器
<a name="tutorial-continue-new-step-4"></a>

現在您已建立兩個 Lambda 函數，請建立狀態機器。在此狀態機器中，`ShouldRestart` 和 `Restart` 狀態表示您在多次執行間中斷工作的方式。

**Example ShouldRestart Choice 狀態**  
以下摘錄顯示 `ShouldRestart``Choice` 狀態。此狀態決定您是否應該重新啟動執行。  

```
"ShouldRestart": {
"Type": "Choice",
"Choices": [
  {
    "Variable": "$.restart.executionCount",
    "NumericGreaterThan": 1,
    "Next": "Restart"
  }
],
```

`$.restart.executionCount` 值包含在初始執行的輸入中。該值會在每次呼叫 `Restart` 函數時減 1，然後在每次後續執行時將該值放置於輸入中。

**Example 重新啟動任務狀態**  
以下摘錄顯示 `Restart``Task` 狀態。此狀態會使用您先前建立的 Lambda 函數來重新啟動執行，以及減少計數，以追蹤要啟動的剩餘執行數目。  

```
"Restart": {
  "Type": "Task",
  "Resource": "arn:aws:lambda:region:123456789012:function:Restart",
  "Next": "Done"
},
```

**建立 狀態機器**

1. 開啟 [Step Functions 主控台](https://console.aws.amazon.com/states/home)，從功能表中選擇**狀態機器**，然後選擇**建立狀態機器**。
**重要**  
請確定您的狀態機器與您先前在[步驟 1](#tutorial-continue-new-step-1) 和[步驟 2](#tutorial-continue-new-step-3) 中建立的 Lambda 函數位於相同的 AWS 帳戶和區域。

1. 選擇**從空白建立**。

1. 為您的狀態機器命名，然後選擇**繼續**在 Workflow Studio 中編輯您的狀態機器。

1. 在本教學課程中，您將在 中撰寫狀態機器的 [Amazon States Language](concepts-amazon-states-language.md)(ASL) 定義[程式碼編輯器](workflow-studio.md#wfs-interface-code-editor)。若要這樣做，請選擇**程式碼**。

1. 移除現有的樣板程式碼並貼上下列程式碼。請記得將此程式碼中的 ARNs 取代為您建立的 Lambda 函數ARNs。

   ```
   {
       "Comment": "Continue-as-new State Machine Example",
       "StartAt": "ConfigureCount",
       "States": {
           "ConfigureCount": {
               "Type": "Pass",
               "Result": {
                   "count": 100,
                   "index": -1,
                   "step": 1
               },
               "ResultPath": "$.iterator",
               "Next": "Iterator"
           },
           "Iterator": {
               "Type": "Task",
               "Resource": "arn:aws:lambda:region:123456789012:function:Iterator",
               "ResultPath": "$.iterator",
               "Next": "IsCountReached"
           },
           "IsCountReached": {
               "Type": "Choice",
               "Choices": [
                   {
                       "Variable": "$.iterator.continue",
                       "BooleanEquals": true,
                       "Next": "ExampleWork"
                   }
               ],
               "Default": "ShouldRestart"
           },
           "ExampleWork": {
               "Comment": "Your application logic, to run a specific number of times",
               "Type": "Pass",
               "Result": {
                 "success": true
               },
               "ResultPath": "$.result",
               "Next": "Iterator"
           },
           "ShouldRestart": {
             "Type": "Choice",
             "Choices": [
               {
                 "Variable": "$.restart.executionCount",
                 "NumericGreaterThan": 0,
                 "Next": "Restart"
               }
             ],
             "Default": "Done"
           },
           "Restart": {
             "Type": "Task",
             "Resource": "arn:aws:lambda:region:123456789012:function:Restart",
             "Next": "Done"
           },
           "Done": {
               "Type": "Pass",
               "End": true 
           }
       }
   }
   ```

1. 為您的狀態機器指定名稱。若要這樣做，請選擇 **MyStateMachine** 預設狀態機器名稱旁的編輯圖示。然後，在**狀態機器組態**中，在**狀態機器名稱方塊中指定名稱**。

   針對本教學課程，輸入名稱 **ContinueAsNew**。

1. （選用） 在**狀態機器組態**中，指定其他工作流程設定，例如狀態機器類型及其執行角色。

   在此教學課程中，請將所有預設選擇保留在**狀態機器設定**中。

   如果您[先前已建立具有狀態機器正確許可的 IAM 角色](procedure-create-iam-role.md)，並想要使用它，請在**許可**中，選取**選擇現有角色**，然後從清單中選擇角色。或選取**輸入角色 ARN**，然後為該 IAM 角色提供 ARN。

1. 在**確認角色建立**對話方塊中，選擇**確認**以繼續。

   您也可以選擇**檢視角色設定**以返回**狀態機器組態**。
**注意**  
如果您刪除 Step Functions 建立的 IAM 角色，Step Functions 稍後無法重新建立該角色。同樣地，如果您修改角色 （例如，從 IAM 政策中的主體移除 Step Functions)，Step Functions 稍後無法還原其原始設定。

1. 將此狀態機器的 Amazon Resource Name (ARN) 儲存在文字檔案中。您需要提供 ARN，同時提供 Lambda 函數啟動新 Step Functions 執行的許可。

## 步驟 4：更新 IAM 政策
<a name="tutorial-continue-new-step-2"></a>

為了確保您的 Lambda 函數具有啟動新 Step Functions 執行的許可，請將內嵌政策連接至您用於 `Restart` Lambda 函數的 IAM 角色。如需詳細資訊，請參閱《*IAM 使用者指南*》中的[內嵌內嵌政策](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html#embed-inline-policy-console)。

**注意**  
您可以更新前一個範例中的 `Resource` 行，以參考 `ContinueAsNew` 狀態機器的 ARN。這將限制政策，使該政策只能啟動特定狀態機器的執行。

****  

```
{
 "Version":"2012-10-17",		 	 	 
 "Statement": [
     {
         "Sid": "VisualEditor0",
         "Effect": "Allow",
         "Action": [
             "states:StartExecution"
         ],
         "Resource": "arn:aws:states:us-east-2:123456789012:stateMachine:ContinueAsNew"
     }
 ]
}
```

## 步驟 5：執行狀態機器
<a name="tutorial-continue-new-step-5"></a>

若要啟動執行，請提供包含狀態機器 ARN 的輸入和 `executionCount`，以指示應啟動新執行的次數。

1.  在 **ContinueAsNew** 頁面上，選擇**開始執行**。

   隨即顯示**開始執行**對話方塊。

1. 在**開始執行**對話方塊中，執行下列動作：

   1. （選用） 輸入自訂執行名稱以覆寫產生的預設值。
**非 ASCII 名稱和記錄**  
Step Functions 接受包含非 ASCII 字元的狀態機器、執行、活動和標籤名稱。由於這類字元會阻止 Amazon CloudWatch 記錄資料，我們建議您僅使用 ASCII 字元，以便您可以追蹤 Step Functions 指標。

   1. 在**輸入**方塊中，輸入下列 JSON 輸入來執行您的工作流程。

      ```
      {
        "restart": {
          "StateMachineArn": "arn:aws:states:region:account-id:stateMachine:ContinueAsNew",
          "executionCount": 4
        }
      }
      ```

   1. 使用 `ContinueAsNew` 狀態機器的 ARN 來更新 `StateMachineArn` 欄位。

   1. 選擇 **Start execution (開始執行)**。

   1. Step Functions 主控台會引導您前往標題為您的執行 ID 的頁面。此頁面稱為*執行詳細資訊*頁面。在此頁面上，您可以在執行進行時或完成後檢閱執行結果。

      若要檢閱執行結果，請在**圖形檢視**中選擇個別狀態，然後選擇[步驟詳細資訊](concepts-view-execution-details.md#exec-details-intf-step-details)窗格上的個別索引標籤，分別檢視每個狀態的詳細資訊，包括輸入、輸出和定義。如需您可以在執行詳細資訊頁面上檢視之*執行資訊的詳細資訊*，請參閱 [執行詳細資訊概觀](concepts-view-execution-details.md#exec-details-interface-overview)。

      **圖形檢視**會顯示四個執行中的第一個。在執行完成之前，它將通過 `Restart` 狀態並啟動新的執行。  
![\[顯示四個執行中第一個執行的執行圖表。\]](http://docs.aws.amazon.com/zh_tw/step-functions/latest/dg/images/execution-test1.png)

      當此執行完成時，您可以查看正在執行的下一個執行。選取最上方的 **ContinueAsNew** 連結來查看執行清單。您應該會同時看到最近關閉的執行，以及 `Restart` Lambda 函數啟動的持續執行。

      所有執行完成後，您應該會在清單中看到四個成功的執行。第一個開始執行會顯示您選擇的名稱，後續的執行具有產生的名稱。  
![\[顯示所有執行已完成的說明性螢幕擷取畫面。\]](http://docs.aws.amazon.com/zh_tw/step-functions/latest/dg/images/execution-test1-complete.png)