添加循环以重复 Azure Logic 应用的工作流中的动作

适用于:Azure 逻辑应用(消耗 + 标准)

若要在逻辑应用工作流中重复作,可以根据方案的需求将 For each 循环或 Until 循环添加到工作流。

注意

正在查找有关循环的 Power Automate 文档? 请参阅 使用循环

根据用例,可以从以下类型的循环作中进行选择:

  • 若要对数组或集合中的项重复一个或多个操作,请将 For each 操作 添加到工作流中。

    或者,如果你有一个可以处理数组并想为每个数组项运行工作流实例的触发器,可以通过在触发器属性中设置“Split on”来对数组进行拆分。

  • 若要重复一个或多个操作直到条件得到满足或特定状态更改,请将 Until 操作 添加到工作流中。

    工作流首先运行循环内的所有操作,然后检查条件或状态。 如果满足该条件,则循环将停止。 否则,循环将继续进行。 有关工作流中可包含的 Until 循环数的默认限制和最大限制,请参阅 并发、循环和反批处理限制

先决条件

  • 一个 Azure 帐户和订阅。 如果没有订阅,可以注册 Azure 帐户

  • 可在其中创建和编辑工作流的逻辑应用资源。 请参阅 什么是 Azure 逻辑应用

  • 要在循环中重复某个操作的逻辑应用资源和工作流,以及启动该工作流的触发器。

    在添加循环操作之前,工作流必须以触发器作为第一步开始。 有关详细信息,请参阅 添加触发器或作以生成工作流

以下步骤使用 Azure 门户,但利用适当的 Azure 逻辑应用扩展,也可使用以下工具来生成逻辑应用工作流:

某些步骤因使用的是消耗工作流还是标准工作流而略有不同。

对于每个

对每个操作仅适用于数组。 此循环会对数组中的每一项重复执行一个或多个操作。 查看有关 对每个 操作的以下注意事项:

  • “For each”操作可处理的数组项数是有限的。 有关此限制,请参阅并发、循环和拆分限制

  • 默认情况下,“For each”操作中的周期或迭代同时并行运行。

    此行为不同于 Power Automate 的 “应用到每个” 循环,其中各次迭代是逐个运行的,也就是按顺序运行。 如果你的使用场景需要顺序处理,则可以For each 迭代设置为每次只运行一个。 例如,如果想使用延迟操作暂停“For each”操作中的下一次迭代,则需要将每个迭代设置为按顺序运行。

    此默认行为的例外是,嵌套“For each”操作的迭代始终按顺序运行,而不是并行运行。 若要在嵌套的 For each 操作中对数组项并发运行操作,请创建并调用子工作流

  • 若要在每次迭代期间从变量操作获得可预测的结果,请按顺序运行这些迭代。 例如,当并发运行的迭代结束时,“递增变量”、“递减变量”和“附加到变量”操作将返回可预测的结果。 但是,在并发运行循环的每次迭代期间,这些操作可能会返回不可预测的结果。

  • For each 循环中,操作使用 item() 函数来引用和处理数组中的每个项目。 如果指定了不在数组中的数据,则工作流将失败。

以下示例工作流会发送网站 RSS 源的每日摘要。 该工作流使用“For each”操作,它会为每个新项发送电子邮件。

  1. Azure 门户中,按指定顺序创建具有以下步骤的逻辑应用工作流:

    • 名为 “发布源项目时”RSS 触发器

      按照以下常规步骤,向 消耗型标准型 逻辑应用工作流添加触发器。

    • 名为“发送电子邮件”的 Outlook.com 或 Office 365 Outlook 操作

      按照以下一般步骤,向 ConsumptionStandard 类型的逻辑应用工作流中添加操作。

  2. 按照相同的一般步骤,在工作流中的 RSS 触发器和 发送电子邮件 操作之间添加 For each 操作。

  3. 现在,构建循环:

    1. 在“对每一项”项中,先在“从前面步骤中选择一个输出”框内单击,然后选择闪电图标。

    2. 从打开的“动态内容”列表中,在 “发布源项时” 下,选择 源链接,它是 RSS 触发器输出的一个数组。

      注意

      如果未显示“源链接”输出,请在触发器部分标签旁边选择“查看更多”。 在动态内容列表中,只能选择前面步骤中的输出。

      屏幕截图显示 Azure 门户和工作流设计器,其中包含一个名为“对每个”的操作以及已打开的动态内容列表。

      完成后,所选数组输出将如以下示例所示:

      屏幕截图显示了工作流设计器和名为“For each”的作,其中选择了数组输出。

    3. 若要对每个数组项运行现有操作,请将“发送电子邮件”操作拖到 For each 循环中。

      现在,工作流如以下示例所示:

      屏幕截图显示了工作流设计器、名为“对每个项”的操作,以及名为“发送电子邮件”的操作,该操作现位于“对每个项”操作内。

  4. 完成后,保存工作流。

  5. 若要手动测试工作流,请在设计器工具栏上选择“ 运行>运行”。

对于每个操作定义 (JSON)

如果使用的是代码视图,则可以在工作流的 JSON 定义中定义 For_each 操作,例如:

"actions": {
   "For_each": {
      "actions": {
         "Send_an_email_(V2)": {
            "type": "ApiConnection",
            "inputs": {
               "body": {
                  "Body": "@{item()}",
                  "Subject": "New CNN post @{triggerBody()?['publishDate']}",
                  "To": "me@contoso.com"
               },
               "host": {
                  "connection": {
                     "name": "@parameters('$connections')['office365']['connectionId']"
                  }
               },
               "method": "post",
               "path": "/v2/Mail"
            },
            "runAfter": {}
         }
      },
      "foreach": "@triggerBody()?['links']",
      "runAfter": {},
      "type": "Foreach"
   }
},

对每项:按顺序运行

默认情况下,对每个操作中的迭代是同时并行运行的。 但是,如果你有嵌套循环或具有预期可预测结果的循环中的变量,则必须一次按顺序运行这些循环。

  1. 在设计器中,选择 For each 操作以打开信息窗格,然后选择 设置

  2. 并发控制下,将设置从 “关闭 ”更改为 “开”。

  3. 并行度 滑块移动到 1

    屏幕截图显示了“对每个”操作、“设置”选项卡,以及已启用的“并发控制”设置,其中并行度滑块设置为 1。

对于每个操作定义 (JSON):按顺序运行

如果你在代码视图中处理工作流的 JSON 定义并使用 For_each 操作,请添加 operationOptions 参数,并将该参数的值设置为 Sequential

"actions": {
   "For_each": {
      "actions": {
         "Send_an_email_(V2)": { }
      },
      "foreach": "@triggerBody()?['links']",
      "runAfter": {},
      "type": "Foreach",
      "operationOptions": "Sequential"
   }
}

直到

“Until”操作运行并重复一个或多个操作,直到满足所需的指定条件。 如果满足该条件,则循环将停止。 否则,循环将继续进行。 有关 Until 操作或迭代次数的默认和最大限制,请参阅 并发、循环和取消批处理限制

以下列表包含可以使用“Until”操作的一些常见场景:

  • 调用某个终结点,直至获得想要的响应。

  • 在数据库中创建记录。 等待该记录中的特定字段获得批准。 继续处理。

默认情况下,Until 操作按以下方式成功或失败:

  • 如果循环中的所有作都成功,并且根据运行后的行为达到循环限制,则 Until 循环会成功。

  • 如果 Until 循环的最后一次迭代中的所有作都成功,则整个 Until 循环将标记为 “成功”。

  • 如果在 Until 循环的最后一次迭代中有任何作失败,则整个 Until 循环将标记为 “失败”。

  • 如果任何操作在除最后一次迭代之外的某次迭代中失败,则下一次迭代将继续运行,并且整个 Until 操作不会被标记为 失败

    若要改为使该操作失败,请在循环的 JSON 定义中通过添加名为 operationOptions 的参数,并将其值设置为 FailWhenLimitsReached,来更改默认行为,例如:

    "Until": {
       "actions": {
         "Execute_stored_procedure": {
           <...>
           }
         },
         "expression": "@equals(variables('myUntilStop'), true)",
         "limit": {
           "count": 5,
           "timeout": "PT1H"
         },
         "operationOptions": "FailWhenLimitsReached",
         "runAfter": {
         "Initialize_variable_8": [
           "Succeeded"
         ]
       },
    "type": "Until"
    }
    

在以下示例工作流中,从每天上午 8:00 开始,“Until”操作递增变量,直到变量的值等于 10。 然后,该工作流会发送一封电子邮件来确认当前值。 此示例使用 Office 365 Outlook,但你可以使用 Azure 逻辑应用支持的任何电子邮件提供程序。 如果使用其他电子邮件帐户,常规步骤保持不变,但看起来略有不同。

  1. Azure 门户中,使用空白工作流创建逻辑应用资源。 请参阅前面的过程。

  2. 在设计器中,按照常规步骤将名为 Recurrence计划 内置触发器添加到 消耗型标准 工作流中。

  3. “重复”触发器中,指定触发器触发的间隔、频率和时间。

    参数
    间隔 1
    频率
    在这些时间 8
    在这几分钟里 00

    频率 设置为 后,会显示 在这些小时在这些分钟

    完成后,重复触发器将如以下示例所示:

    屏幕截图显示了 Azure 门户和工作流设计器,其中已配置重复触发器参数。

  4. 在触发器下,按照以下常规步骤将名为 Initialize variablesVariables 内置操作添加到 消耗型标准 逻辑应用工作流中。

  5. Initialize 变量 作中,提供以下值:

    参数 描述
    名称 限制 变量的名称
    类型 整数 变量的数据类型
    0 变量的起始值

    屏幕截图显示了 Azure 门户、工作流设计器,以及名为“初始化变量”的内置操作及其参数。

  6. 初始化变量 操作下,按照以下一般步骤,将名为 Until控制 内置操作添加到你的 消耗型标准型 逻辑应用工作流中。

  7. 在“Until”操作中,提供以下值以设置循环的停止条件。

    1. “循环直到 ”框中选择,然后选择闪电图标以打开动态内容列表。

    2. 从列表中的“变量”下,选择名为“Limit”的变量。

    3. “计数”下,输入 10 作为比较值。

    屏幕截图显示了一个工作流以及名为“Until”的内置操作,以及所述的值。

  8. “直到”操作中,选择+>“添加操作”

  9. 按照以下常规步骤,将名为 Increment variableVariables 内置操作添加到 ConsumptionStandard 逻辑应用工作流中的 Until 操作。

  10. 在“递增变量”操作中,提供以下值以将 Limit 变量的值递增 1:

    参数
    限制 选择“Limit”变量。
    1

    屏幕截图显示了一个名为 Until 的工作流和内置作,其限制设置为“限制”变量,“值”设置为 1。

  11. Until 操作外部和内部,按照以下常规步骤在 消耗型标准型 逻辑应用工作流中添加用于发送电子邮件的操作。

    此示例继续使用名为“发送电子邮件”的 Office 365 Outlook 操作。

  12. 在电子邮件操作中,提供以下值:

    参数 描述
    < email-address@domain> 收件人的电子邮件地址。 若要进行测试,请使用你自己的电子邮件地址。
    主题 “Limit”变量的当前值为:Limit 电子邮件主题。 对于此示例,请确保包括 Limit 变量,以确认当前值满足指定的条件:

    1.在 “主题 ”框中选择,然后选择闪电图标。

    2. 从打开的动态内容列表中,在 “变量 ”部分标题旁边,选择“ 查看更多”。

    3. 选择“Limit”。
    正文 < email-content> 你要发送的电子邮件消息内容。 对于本例,输入你所需的任何文本。

    完成后,电子邮件操作将如以下示例所示:

    屏幕截图显示了一个名为“使用属性值发送电子邮件”的工作流和操作。

  13. 保存工作流。

测试工作流

若要手动测试逻辑应用工作流,请执行以下作:

  • 在设计器工具栏上,从 “运行 ”选项中选择“ 运行”。

在你的工作流开始运行后,你将收到一封包含指定内容的电子邮件:

屏幕截图显示了从示例工作流收到的示例电子邮件。

防止无限循环

Until 动作会根据可选的 CountTimeout 参数停止执行。 请确保相应地设置这些参数值:

参数 描述
计数 在循环退出之前运行的最大迭代次数。

有关工作流可以有的“Until”操作数的默认值和最大限制,请参阅并发、循环和拆分限制
超时 在循环退出前,Until 操作(包括所有迭代)允许运行的最长时间。 此值以 ISO 8601 格式指定,每次迭代时都会评估该值。

如果循环中的任何操作花费的时间超过超时限制,当前迭代便不会停止。 但是,由于满足超时限制条件,因此下一个迭代不会启动。

有关“超时”值的默认值和最大限制,请参阅并发、循环和拆分限制

查看 Until 循环迭代的运行历史记录

查看包含 Until 循环的工作流的运行历史记录时,循环内操作的详细状态和结果仅在整个循环完成其运行后可用。 虽然 Until 循环仍在执行其迭代,但循环操作会显示 “正在运行 ”状态,但在循环退出之前,无法展开或遍历单个迭代结果。

满足以下条件之一时,循环将退出:

  • 指定的表达式的计算结果为 true
  • 循环达到 Count 限制。
  • 循环达到 超时 限制。

循环完成后,可以选择运行历史记录中的 Until 操作以查看每次迭代以及该迭代中子操作的状态。

注意

如果 Until 循环长时间运行,则必须等待循环完全完成,然后才能检查单个迭代结果的运行历史记录。 若要监视长时间运行的正在进行的循环,请考虑在循环中添加独立发出状态的日志记录或通知操作,例如,将消息发送到队列或更新并行分支可以读取的变量。

“Until”定义(JSON)

如果使用的是代码视图,则可以在工作流的 JSON 定义中定义 Until 操作,例如:

"actions": {
   "Initialize_variable": {
      // Definition for initialize variable action
   },
   "Send_an_email": {
      // Definition for send email action
   },
   "Until": {
      "type": "Until",
      "actions": {
         "Increment_variable": {
            "type": "IncrementVariable",
            "inputs": {
               "name": "Limit",
               "value": 1
            },
            "runAfter": {}
         }
      },
      "expression": "@equals(variables('Limit'), 10)",
      // To prevent endless loops, an "Until" loop 
      // includes these default limits that stop the loop. 
      "limit": { 
         "count": 60,
         "timeout": "PT1H"
      },
      "runAfter": {
         "Initialize_variable": [
            "Succeeded"
         ]
      }
   }
}

此示例中的 Until 循环调用一个 HTTP 终结点,该终结点会创建一个资源。 当 HTTP 响应主体返回 Completed 状态时,循环停止。 为防止无限循环,该循环在发生下列任一条件时也会停止:

  • 循环运行了 10 次(由 count 属性指定)。 默认值为 60 次。

  • 循环已运行两小时(由 timeout 属性以 ISO 8601 格式指定)。 默认值为一小时。

"actions": {
   "myUntilLoopName": {
      "type": "Until",
      "actions": {
         "Create_new_resource": {
            "type": "Http",
            "inputs": {
               "body": {
                  "resourceId": "@triggerBody()"
               },
               "url": "https://domain.com/provisionResource/create-resource"
            },
            "runAfter": {},
            "type": "ApiConnection"
         }
      },
      "expression": "@equals(body('Create_new_resource'), 'Completed')",
      "limit": {
         "count": 10,
         "timeout": "PT2H"
      },
      "runAfter": {}
   }
}