在 Azure 逻辑应用 的工作流中运行循环以重复执行操作

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

要对数组或集合中的每个项执行相同操作,或重复操作直到逻辑应用工作流中的某项完成,请在工作流中分别添加名为“For each”或“Tiel”的控制操作:

Action 任务
对于每个 对数组或集合项重复一个或多个操作。 仅适用于数组和集合。

提示:如果你有一个处理数组的触发器,想为每个数组项目运行一个工作流实例,可以设置触发器的 Split on 属性 来进行 数组清批处理

更多信息请参见 并发、循环和批次限制
Until 重复一个或多个动作,直到满足某个条件或特定状态发生变化。

你的工作流程先运行循环中的所有操作,然后检查条件或状态。 如果满足该条件,则循环将停止。 否则,循环将继续进行。

更多信息请参见 并发、循环和批次限制

本指南展示了如何将循环添加到工作流程中,顺序运行迭代,并防止无休止的循环。 跳到你想做的任务:

注意

有关 Power Automate 的文档,请参阅 使用循环

先决条件

  • 一个 Azure 帐户和订阅。 获取 Azure 帐户

  • 你要在其中运行循环的逻辑应用工作流,包括用于启动该工作流的触发器。

    在添加循环动作之前,你的工作流程必须 先从触发器作为 第一步开始。

本指南使用Azure门户,但你也可以使用Visual Studio Code和相应的Azure 逻辑应用扩展来构建逻辑应用的工作流程:

各循环的注意事项

“For 每个动作”会对每个数组或集合项重复一个或多个操作。

  • For 每个动作只对数组和集合有效。

  • For each 操作可处理数量有限的数组项

  • 默认情况下, 对于每个 动作,迭代是并行运行的。 需要了解的关键行为:

    Behavior 含义
    默认并行 Power Automate 的 “对每个项应用”循环不同,各次迭代不会逐个运行。

    如果你的场景需要顺序处理,请参见 “顺序运行每个迭代”。 例如,要 在一个操作 中暂停下一次迭代,使用 延迟动作,设置每次迭代顺序运行。
    嵌套循环 嵌套的 对于每个 操作始终按顺序运行。 要并行运行,可以 创建并调用子工作流
    变量 增量变量递减变量附加变量 在并行循环中可能会返回不可预测的结果。 为了确保循环中的变量在每次迭代中对这些变量的操作产生可预测的结果,请顺序 运行循环
  • For each 循环中,操作使用 item() 函数来引用和处理数组中的每个项目。 如果指定了不在数组中的数据,则工作流将失败。

在工作流中添加 For each 循环

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

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

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

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

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

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

  2. 在设计器中,根据工作流类型,按照相应的一般步骤,在触发器与 发送电子邮件 操作之间添加名为 For each 的操作:

  3. 现在,构建循环:

    1. For each 操作中,单击 从前面的步骤中选择一个输出 框以查看输入选项,然后选择闪电图标。

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

      注意

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

      显示 Azure 门户、工作流设计器、名为“For each”的操作以及已打开的动态内容列表的截图。

      以下示例展示了所选数组输出:

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

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

      你的工作流程示例如下:

      显示工作流设计器的屏幕截图,其中包含名为“For each”的操作,以及现在位于“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 操作不会被标记为 失败

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

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

在工作流程中添加一个“直到”循环

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

  1. Azure 门户中,使用空白工作流创建逻辑应用资源。

  2. 在设计器中,按照你的工作流程类型,按照一般步骤添加名为“Recurrence”的Schedule内置触发器:

  3. 重复周期 触发器中,提供以下信息:

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

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

    以下示例显示了 重复 触发器的显示方式:

    显示 Azure 门户和工作流设计器且已设置重复触发器参数的屏幕截图。

  4. 在设计器中,按照你的工作流程类型,按照一般步骤添加变量内置操作,称为初始化变量

  5. 初始化变量 操作中,提供以下信息:

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

    截图显示了Azure门户、工作流设计器和内置操作Initialize变量,还有参数。

  6. 初始化变量操作中,按照你的工作流程类型,按照一般步骤添加名为“直到”的控制内置动作:

  7. “直到 ”动作中,设置循环的停止条件:

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

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

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

    显示工作流以及名为“Until”的内置操作(包含所述值)的屏幕截图。

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

  9. 根据工作流类型,按照以下常规步骤,将名为递增变量变量内置操作添加到Until操作中:

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

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

    截图显示了工作流程和一个名为“直到”的内置动作,限制设置为限制变量,值设为1。

  11. Until 操作外部并在其下方,根据你的工作流类型,按照以下常规步骤添加一个发送电子邮件的操作:

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

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

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

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

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

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

    以下示例展示了您的电子邮件操作的显示方式:

    截图显示了一个名为“发送带有属性值的邮件”的工作流程和操作。

  13. 保存工作流。

测试工作流

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

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

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

截图显示了示例工作流程收到的邮件样本。

防止无限循环

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

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

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

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

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

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

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

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

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

循环完成后,可以选择运行历史记录中的 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": {}
   }
}

后续步骤