

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 在 Step Functions 中使用 Lambda 函数迭代循环
<a name="tutorial-create-iterate-pattern-section"></a>

在本教程中，将实现使用状态机和 AWS Lambda 函数迭代循环特定次数的设计模式。

无论何时您需要跟踪状态机中的循环数量，都可以使用此设计模式。此实现可帮助您将大型任务或长时间运行的执行分解为较小的块，或者在特定数量的事件之后结束执行。您可以使用类似的实现来定期结束和重启长时间运行的执行，以避免超过 AWS Step Functions AWS Lambda、或其他 AWS 服务的服务配额。

在开始之前，请仔细阅读[创建使用 Lambda 的 Step Functions 状态机](tutorial-creating-lambda-state-machine.md)教程，确保您熟悉如何同时使用 Lambda 和 Step Functions。

## 第 1 步：创建迭代计数的 Lambda 函数
<a name="create-iterate-pattern-step-1"></a>

通过使用 Lambda 函数，您可以跟踪状态机中的循环迭代次数。以下 Lambda 函数接收 `count`、`index` 和 `step` 的输入值。它返回这些值及更新的 `index` 和一个名为 `continue` 的布尔值。如果 `continue` 小于 `true`，Lambda 函数将 `index` 设置为 `count`。

然后，状态机实现 `Choice` 状态：在 `continue` 为 `true` 时执行一些应用程序逻辑，为 `false` 时，则退出。

### 创建 Lambda 函数
<a name="create-iterate-pattern-create-lambda-function"></a>

1. 登录 [Lambda 控制台](https://console.aws.amazon.com/lambda/home)，然后选择**创建函数**。

1. 在**创建函数**页面上，选择**从头开始创作**。

1. 在**基本信息**部分中，配置您的 Lambda 函数：

   1. 对于**函数名称**，请输入 `Iterator`。

   1. 对于 **Runtime (运行时)**，选择 **Node.js**。

   1. 在**更改默认执行角色**中，选择**创建具有基本 Lambda 权限的新角色**。

   1. 选择**创建函数**。

1. 将 Lambda 函数的以下代码复制到**代码源**中。

   ```
   export const handler = function (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` 的输入值。它将 `index` 递增 `step` 的值，并返回这些值及布尔值 `continue`。如果 `index` 小于 `count`，`continue` 的值为 `true`。

1. 选择**部署**。

## 第 2 步：测试 Lambda 函数
<a name="create-iterate-pattern-step-2"></a>

使用数值运行您的 Lambda 函数，以查看其运行情况。可以为模拟迭代的 Lambda 函数提供输入值。

### 测试 Lambda 函数
<a name="create-iterate-pattern-test-lambda-function"></a>

1. 选择**测试**。

1. 在 **配置测试事件**对话框中，在**事件名称**框中输入 `TestIterator`。

1. 使用以下内容替换示例数据。

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

   这些值模拟在迭代期间来自状态机的内容。Lambda 函数将递增索引，当索引小于 `count` 时，将对于 `continue` 返回 `true`。在此测试中，索引已增加到 `5`。测试将 `index` 递增到 `6`，并将 `continue` 设置为 `true`。

1. 选择**创建**。

1. 选择**测试**来测试您的 Lambda 函数。

   测试结果显示在**执行结果**选项卡中。

1. 要查看执行结果，请选择**输出**选项卡。

   ```
   {
     "index": 6,
     "step": 1,
     "count": 10,
     "continue": true
   }
   ```
**注意**  
如果将 `index` 设置为 `9` 并再次测试，则 `index` 递增为 `10`，而 `continue` 将为 `false`。

## 第 3 步：创建状态机
<a name="create-iterate-pattern-step-3"></a>

**在您离开 Lambda 控制台之前...**  
复制 Lambda 函数 ARN。将其粘贴到笔记中。下一步中需要使用该值。

接下来，您将创建具有以下状态的状态机：
+ `ConfigureCount`：为 `count`、`index` 和 `step` 设置默认值。
+ `Iterator`：引用您之前创建的 Lambda 函数，同时传入在 `ConfigureCount` 中配置的值。
+ `IsCountReached`：根据从 `Iterator` 函数返回的值，继续循环或进入 `Done` 状态的 Choice 状态。
+ `ExampleWork`：需要完成的工作的存根。在此示例中，工作流程有一个 `Pass` 状态，但在实际解决方案中，可能会使用 `Task`。
+ `Done`：工作流程的结束状态。

要在控制台中创建状态机，请执行以下操作：

1. 打开 [Step Functions 控制台](https://console.aws.amazon.com/states/home)，然后选择**创建状态机**。
**重要**  
您的状态机必须与您的 Lambda 函数位于同一个 AWS 账户和区域中。

1. 选择**空白**模板。

1. 在**代码**窗格中，粘贴以下用于定义状态机的 JSON。

   有关 Amazon States Language 的更多信息，请参阅[状态机结构](statemachine-structure.md)。

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

1. 将 `Iterator Resource` 字段替换为您之前创建的 `Iterator` Lambda 函数的 ARN。

1. 选择**配置**，然后为状态机输入**名称**，例如 `IterateCount`。
**注意**  
状态机、执行和活动任务的名称长度不得超过 80 个字符。对于您的账户和 AWS 地区，这些名称必须是唯一的，并且不得包含以下任何内容：  
空格
通配符 (`? *`)
方括号字符 (`< > { } [ ]`)
特殊字符 (`" # % \ ^ | ~ ` $ & , ; : /`)
控制字符（`\\u0000` - `\\u001f` 或 `\\u007f` - `\\u009f`）
Step Functions 对于状态机、执行、活动和标签接受包含非 ASCII 字符的名称。由于此类字符会 CloudWatch 阻止亚马逊记录数据，因此我们建议您仅使用 ASCII 字符，这样您就可以跟踪 Step Functions 的指标。

1. 对于**类型**，接受默认值**标准**。对于**权限**，选择**创建新角色**。

1. 选择**创建**，然后**确认**角色创建。

## 第 4 步：启动新的执行
<a name="create-iterate-pattern-step-4"></a>

在创建您的状态机后，可以开始执行。

1. 在**IterateCount**页面上，选择 “**开始执行**”。

1. （可选）输入自定义执行名称，以便覆盖生成的默认执行名称。
**非 ASCII 名称和日志记录**  
Step Functions 对于状态机、执行、活动和标签接受包含非 ASCII 字符的名称。由于此类字符会 CloudWatch 阻止亚马逊记录数据，因此我们建议您仅使用 ASCII 字符，这样您就可以跟踪 Step Functions 的指标。

1. 选择**开始执行**。

   此时将开始状态机的新执行，并显示正在运行的执行。  
![\[状态机图显示蓝色迭代器状态，表示正在进行的状态。\]](http://docs.aws.amazon.com/zh_cn/step-functions/latest/dg/images/tutorial-create-iterate-running.png)

   执行逐步递增，使用您的 Lambda 函数跟踪计数。在每次迭代时，它都会执行在状态机中处于 `ExampleWork` 状态引用的示例工作。

   计数达到您的状态机中 `ConfigureCount` 状态中指定的数值后，执行停止迭代并结束。  
![\[状态机图以绿色显示迭代器和 Done 状态，表示两者都已成功。\]](http://docs.aws.amazon.com/zh_cn/step-functions/latest/dg/images/tutorial-create-iterate-done.png)