你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
适用对象:Azure 逻辑应用(消耗)
若要仅在另一组操作成功或失败之后运行一组操作,可以将依赖的操作嵌套在作用域内。 如果你希望将各个操作组织为逻辑组,评估该组的状态并执行基于作用域状态的操作,则此结构非常有用。 当某个作用域中的所有操作都完成运行后,该作用域也确定了其自己的状态。 例如,当希望实现异常和错误处理时可以使用作用域。
若要检查作用域的状态,可以使用与用来确定逻辑应用运行状态(例如“已成功”、“已失败”、“已取消”,等等)的条件相同的条件。 默认情况下,当作用域的所有操作都成功时,作用域的状态将被标记为“已成功”。 但是,当作用域中有任何操作失败或被取消时,作用域的状态将被标记为“已失败”。 有关作用域的限制,请参阅限制和配置。
例如,下面是一个高级别逻辑应用,它使用作用域来运行特定操作并使用一个条件来检查作用域的状态。 如果作用域中有任何操作失败或意外终止,则作用域将被相应地标记为“已失败”或“已中止”,并且逻辑应用将发送一条“作用域已失败”消息。 如果作用域中的所有操作都成功,则逻辑应用会发送一条“作用域已成功”消息。
               
              
            
先决条件
- 一个 Azure 帐户和订阅。 如果没有订阅,可以注册免费的 Azure 帐户。 
- Azure Logic Apps 支持的任何电子邮件服务提供商的邮箱账户。 - 此示例使用的是 Outlook.com。 如果使用其他提供程序,则一般流程保持不变,但出现的 UI 会有所不同。 
- 一个必应地图密钥。 若要获取此密钥,请参阅获取必应地图密钥。 
- 有关逻辑应用的基础知识 
创建示例逻辑应用
首先,创建此示例逻辑应用,以便之后可以添加作用域:
               
              
            
- 一个“计划 - 定期”触发器,用于按你指定的时间间隔检查必应地图服务
- 一个“必应地图 - 获取路线”操作,用于检查两个位置之间的旅行时间
- 一个条件操作,用于检查旅行时间是否超出了你指定的旅行时间
- 一个在当前旅行时间超出指定时间时向你发送电子邮件的操作
你可以随时保存逻辑应用,因此请频繁保存你的工作。
- 如果尚未登录到 Azure 门户,请进行登录。 创建空白逻辑应用。 
- 使用以下设置添加“计划 - 定期”触发器:时间间隔 = 1 并且频率 =“Minute”   - 提示 - 若要在视觉方面简化视图并在设计器中隐藏每个操作的详细信息,请在执行这些步骤时折叠每个操作的形状。 
- 添加“必应地图 - 获取路线”操作。 - 如果尚没有必应地图连接,则会要求你创建一个连接。 - 设置 - 值 - 说明 - 连接名称 - BingMapsConnection - 提供连接的名称。 - API 密钥 - < your-Bing-Maps-key> - 输入以前接收的必应地图密钥。 
- 根据此图像下方的表中所示设置“获取路线”操作:   - 有关这些参数的详细信息,请参阅计算路线。 - 设置 - 值 - 说明 - 路标 1 - < 起点> - 输入路线的起点。 - 路标 2 - < 终点> - 输入路线的目的地。 - 避免 - 无 - 输入路线上需要避免的项目,例如高速公路、收费站等。 有关可能的值,请参阅计算路由。 - 优化 - timeWithTraffic - 选择一个参数来优化路线,例如距离、时间(在使用当前交通信息的情况下),等等。 此示例使用以下值:timeWithTraffic - 距离单位 - < your-preference> - 输入要用来计算路线的距离单位。 此示例使用以下值:Mile - 旅行模式 - 驾车 - 输入路线的旅行模式。 此示例使用以下值:Driving - 运输日期/时间 - 无 - 仅适用于运输模式。 - 运输日期/时间类型 - 无 - 仅适用于运输模式。 
 
- 添加条件,检查当前交通状况下的旅行时间是否超出了指定时间。 对于本示例,请遵循以下步骤: - 重命名条件并提供以下说明:交通时间是否超过指定时间 
- 在最左侧的列中,在“选择值”框内部选择后将会显示动态内容列表。 从该列表中,选择“旅行期间 - 交通”字段(以秒为单位)。   
- 在中间的框中选择此运算符:is greater than 
- 在最右侧的列中,输入此比较值(以秒为单位,相当于 10 分钟):600 - 完成后,条件如以下示例所示:   
 
- 在“True”分支中,为电子邮件提供程序添加“发送电子邮件”操作。 按照此图像下的步骤设置此操作:   - 在“收件人”字段中,输入电子邮件地址以进行测试。 
- 在“主题”字段中,输入以下文本: - Time to leave: Traffic more than 10 minutes
- 在“正文”字段中,输入带尾随空格的以下文本: - Travel time:- 当光标出现在“正文”字段中时,动态内容列表将保持打开状态,以便你可以选择此时可用的任何参数。 
- 在动态内容列表中,选择“表达式”。 
- 查找并选择“div()”函数。 将游标置于函数的括号内。 
- 当游标位于函数的括号内时,选择“动态内容”,以便显示动态内容列表。 
- 在“获取路线”部分,选择“旅行期间 - 交通”字段。   
- 在此字段解析为 JSON 格式后,添加一个逗号 (),后跟数字 - ,,以便将“旅行期间 - 交通”中的值从秒转换为分钟。- 60- div(body('Get_route')?['travelDurationTraffic'],60)- 现在,表达式应如下例所示:   
- 完成后,请选择“确定”。 
 - 在表达式解析后,添加带有前导空格的以下文本: - minutes- “正文”字段现在如下例所示:   
 
- 保存逻辑应用。 
接下来,添加一个作用域,以便可以对特定操作进行分组并评估它们的状态。
添加作用域
- 如果还未执行此操作,请在工作流设计器中打开逻辑应用。 
- 在所需的工作流位置添加一个作用域。 例如,若要在逻辑应用工作流中的现有步骤之间添加作用域,请按照下列步骤操作: - 将指针移到要添加作用域的箭头上。 选择“加号 ()”+“添加操作”。>   
- 在搜索框中,输入“作用域”作为筛选器。 选择“作用域”操作。 
 
将步骤添加到作用域
- 现在,添加要在作用域内运行的步骤,或拖动要在作用域内运行的现有步骤。 对于本例,请将以下操作拖动到作用域中: - 获取路线
- 交通时间是否超过指定时间,包括“true”和“false”分支
 - 现在,逻辑应用如下例所示:   
- 在作用域下,添加一个条件,用以检查作用域的状态。 重命名条件并提供以下说明:如果作用域失败   
- 在此条件下,添加这些表达式,检查作用域的状态是否等于“失败”或“已中止”。 - 要另外添加一行,请选择“添加”。 
- 在每一行中,选择左侧框内部,以显示动态内容列表。 在动态内容列表中,选择“表达式”。 在编辑框中,输入此表达式,然后选择“确定”: - actions('Scope')?['status']  
- 对于这两行,选择“is equal to”作为其运算符。 
- 对于比较值,在第一行中输入 - Failed。 在第二行中,输入- Aborted。- 完成后,条件如以下示例所示:   - 现在,设置条件的 - runAfter属性,以便条件检查作用域状态并运行在后续步骤中定义的匹配操作。
- 在“如果作用域失败”条件中,选择“省略号”(...) 按钮,然后选择“在以下事件后配置运行”。   
- 选择所有这些作用域状态:“成功”、“失败”、“跳过”、“已超时”   
- 完成后,选择“完成”。 该条件现在显示“信息”图标。 
 
- 在“True”和“False”分支中,根据每个作用域状态添加要执行的操作,例如,发送电子邮件或消息。   
- 保存逻辑应用。 
已完成的逻辑应用如下例所示:
               
              
            
测试工作流
在设计器工具栏上选择“运行”“运行”。> 如果所有作用域的操作都成功,则会收到 作用域成功 消息。 如果任何范围操作未成功,则会收到“范围失败”消息。
JSON 定义
如果在代码视图中工作,则可以改为在工作流的 JSON 定义中定义范围。 以下示例显示了基本作用域的定义:
{
   "actions": {
      "Scope": {
         "type": "Scope",
         "actions": {
            "Http": {
               "inputs": {
                   "method": "GET",
                   "uri": "https://www.bing.com"
               },
               "runAfter": {},
               "type": "Http"
            }
         }
      }
   }
}
The following example shows the JSON definition for the trigger and actions in the preceding workflow:
``` json
"triggers": {
  "Recurrence": {
    "type": "Recurrence",
    "recurrence": {
       "frequency": "Minute",
       "interval": 1
    }
  }
},
"actions": {
  "If_scope_failed": {
    "type": "If",
    "actions": {
      "Scope_failed": {
        "type": "ApiConnection",
        "inputs": {
          "body": {
            "Body": "Scope failed. Scope status: @{action('Scope')}",
            "Subject": "Scope failed",
            "To": "<your-email@domain.com>"
          },
          "host": {
            "connection": {
              "name": "@parameters('$connections')['outlook']['connectionId']"
            }
          },
          "method": "post",
          "path": "/Mail"
        },
        "runAfter": {}
      }
    },
    "else": {
      "actions": {
        "Scope_succeeded": {
          "type": "ApiConnection",
          "inputs": {
            "body": {
              "Body": "Scope succeeded. Scope status: @{action('Scope')}",
              "Subject": "Scope succeeded",
              "To": "<your-email@domain.com>"
            },
            "host": {
              "connection": {
               "name": "@parameters('$connections')['outlook']['connectionId']"
              }
            },
            "method": "post",
            "path": "/Mail"
          },
          "runAfter": {}
        }
      }
    },
    "expression": {
      "or": [ 
         {
            "equals": [ 
              "@action('Scope')",
              "Failed"
            ]
         },
         {
            "equals": [
               "@action('Scope')",
               "Aborted"
            ]
         } 
      ]
    },
    "runAfter": {
      "Scope": [
        "Failed",
        "Skipped",
        "Succeeded",
        "TimedOut"
      ]
    }
  },
  "Scope": {
    "type": "Scope",
    "actions": {
      "Get_route": {
        "type": "ApiConnection",
        "inputs": {
          "host": {
            "connection": {
              "name": "@parameters('$connections')['bingmaps']['connectionId']"
            }
          },
          "method": "get",
          "path": "/REST/V1/Routes/Driving",
          "queries": {
            "distanceUnit": "Mile",
            "optimize": "timeWithTraffic",
            "travelMode": "Driving",
            "wp.0": "<start>",
            "wp.1": "<end>"
          }
        },
        "runAfter": {}
      },
      "If_traffic_time_is_more_than_specified_time": {
        "type": "If",
        "actions": {
          "Send_mail_when_traffic_exceeds_10_minutes": {
            "type": "ApiConnection",
            "inputs": {
              "body": {
                 "Body": "Travel time:@{div(body('Get_route')?['travelDurationTraffic'],60)} minutes",
                 "Subject": "Time to leave: Traffic more than 10 minutes",
                 "To": "<your-email@domain.com>"
              },
              "host": {
                "connection": {
                   "name": "@parameters('$connections')['outlook']['connectionId']"
                }
              },
              "method": "post",
              "path": "/Mail"
            },
            "runAfter": {}
          }
        },
        "expression": {
          "and" : [
            {
               "greater": [ 
                  "@body('Get_route')?['travelDurationTraffic']", 
                  600
               ]
            }
          ]
        },
        "runAfter": {
          "Get_route": [
            "Succeeded"
          ]
        }
      }
    },
    "runAfter": {}
  }
},