流程控制 
数据流用来编排处理器的调用逻辑,支持使用 flows对查询节点数据处理,JS数据流处理适用于较为复杂的业务逻辑。
flows处理器为我们提供完整的数据流处理,可以提供数据处理器一套流程, 数据流可以作为处理器使用,命名空间为 flows.<处理器名称>查询节点可以引用除自身以外的其他数据流。
上下文数据引用 
- 可在全局使用 
{{$in}}变量访问调用时的传入参数; - 可在全局使用 
{{$res}}变量访问各点返回值; - 可在节点使用 
{{$out}}变量访问处理器返回值;outs用于字段声明当前节点的返回值, 如不声明返回处理器的运行结果。 output字段用于声明数据流的输出结果, 如不声明返回所有节点的运行结果。
| 变量 | 类型 | 说明 | 使用范围 | 示例 | 
|---|---|---|---|---|
{{$in}} | array<any> | 作为处理器被调用时传入的参数表, 支持使用数组下标访问指定参数, 例如: {{$in.0}} 第 1 个参数, {{$in.1}} 第 2 个参数, | nodes[*].args, nodes[*].outs, output | {{$in}}, {{$in.0}},{{$in.0.name}} | 
{{$res}} | [key:string]:any | 查询节点返回值(nodes[*].outs) 映射表, 支持使用查询节点名称访问特定查询节点返回值。例如 {{$res.node1.0}} node1 的第一返回值。 | nodes[*].args, nodes[*].outs, output | {{$res}}, {{$res.node1.0.name}}, {{$res.node2.manu_id}} | 
{{$out}} | any | 查询节点的处理器(process)返回值,支持使用 . 访问 Object /Array 数值 | nodes[*].outs | {{out}}, {{out.name}}, {{out.0}} | 
内置的流程控制处理器 
| 处理器 | 别名 | 说明 | 
|---|---|---|
| xiang.flow.For | xiang.helper.For | 遍历数据 | 
| xiang.flow.Each | xiang.helper.Each | 遍历数据 | 
| xiang.flow.Case | xiang.helper.Case | Case 流程控制 | 
| xiang.flow.IF | xiang.helper.IF | IF 流程控制 | 
| xiang.flow.Return | xiang.helper.Return | 返回输入数据 | 
| xiang.flow.Throw | xiang.helper.Throw | 抛出异常并结束程序 | 
示例代码: 
Case 流程控制示例 
以下示例展示了如何使用 Case 流程控制进行条件判断,包括单条件和多条件 OR 逻辑的使用场景:
json
{
  "label": "Case流程控制示例",
  "version": "1.0.0",
  "description": "演示Case流程控制的使用方法",
  "nodes": [
    {
      "name": "条件判断",
      "process": "xiang.flow.Case",
      "args": [
        {
          "name": "多条件OR逻辑",
          "when": [
            { "用户": "张三", "=": "李四" },
            { "or": true, "用户": "李四", "=": "李四" }
          ],
          "process": "flows.处理A",
          "args": ["world"]
        },
        {
          "name": "单条件判断",
          "when": [{ "用户": "张三", "=": "张三" }],
          "process": "flows.处理B",
          "args": ["foo"]
        }
      ]
    }
  ]
}在上面的示例中:
第一个条件判断使用了 OR 逻辑:
- 检查 
用户是否等于李四 - 或者检查 
用户是否等于李四 - 如果任一条件满足,则执行 
flows.处理A 
- 检查 
 第二个条件判断使用了单一条件:
- 检查 
用户是否等于张三 - 如果条件满足,则执行 
flows.处理B 
- 检查 
 
条件判断会按顺序执行,当遇到第一个条件满足时,将执行对应的处理器并返回结果。
在flows里面使用 xiang.flow.IF 
json
{
  "label": "测试flows",
  "version": "1.0.0",
  "description": "测试flows",
  "nodes": [
    {
      "name": "检查数据",
      "process": "xiang.flow.IF",
      "args": [
        {
          "name": "忽略处理",
          "when": [{ "忽略处理": "{{$res}}", "is": "notnull" }],
          "process": "xiang.flow.Throw",
          "args": ["忽略处理", 400]
        }
      ]
    }
  ]
}IF 流程控制示例 
以下示例展示了如何使用 IF 流程控制进行条件判断,包括单条件和多条件 OR 逻辑的使用场景:
json
{
  "label": "IF流程控制示例",
  "version": "1.0.0",
  "description": "演示IF流程控制的使用方法",
  "nodes": [
    {
      "name": "条件判断",
      "process": "xiang.flow.IF",
      "args": [
        {
          "name": "多条件OR逻辑",
          "when": [
            { "用户": "张三", "=": "李四" },
            { "or": true, "用户": "李四", "=": "李四" }
          ],
          "process": "flows.处理A",
          "args": ["world"]
        },
        {
          "name": "单条件判断",
          "when": [{ "用户": "张三", "=": "张三" }],
          "process": "flows.处理B",
          "args": ["foo"]
        }
      ]
    }
  ]
}在上面的示例中:
第一个条件判断使用了 OR 逻辑:
- 检查 
用户是否等于李四 - 或者检查 
用户是否等于李四 - 如果任一条件满足,则执行 
flows.处理A 
- 检查 
 第二个条件判断使用了单一条件:
- 检查 
用户是否等于张三 - 如果条件满足,则执行 
flows.处理B 
- 检查 
 
条件判断会按顺序执行,当遇到第一个条件满足时,将执行对应的处理器并返回结果。
Each 流程控制示例 
Each 流程控制支持以下数据类型的遍历:
- 整数类型(int、uint 及其变体):将遍历从 0 到该数值的范围
 - 数组/切片类型:遍历数组中的每个元素
 - Map 类型:遍历映射中的键值对
 - 结构体类型:将结构体转换为 Map 后遍历其字段
 
以下示例展示了不同数据类型的遍历用法:
json
{
  "label": "Each流程控制示例",
  "version": "1.0.0",
  "description": "演示Each流程控制的使用方法",
  "nodes": [
    {
      "name": "遍历整数范围",
      "process": "xiang.flow.Each",
      "args": [
        5,
        {
          "process": "flows.处理数值",
          "args": ["::key", "::value"]
        }
      ]
    },
    {
      "name": "遍历数组",
      "process": "xiang.flow.Each",
      "args": [
        ["A", "B", "C", "D"],
        {
          "process": "flows.处理数组元素",
          "args": ["::key", "::value"]
        }
      ]
    },
    {
      "name": "遍历对象",
      "process": "xiang.flow.Each",
      "args": [
        {
          "name": "张三",
          "age": 18,
          "city": "北京"
        },
        {
          "process": "flows.处理对象属性",
          "args": ["::key", "::value"]
        }
      ]
    },
    {
      "name": "遍历结构体",
      "process": "xiang.flow.Each",
      "args": [
        {
          "ID": 1,
          "Name": "产品A",
          "Price": 99.9,
          "Status": "active"
        },
        {
          "process": "flows.处理结构体字段",
          "args": ["::key", "::value"]
        }
      ]
    }
  ]
}在上面的示例中:
遍历整数范围示例:
- 遍历从 0 到 4 的整数范围
 - 对每个数值调用 flows.处理数值 处理器
 - ::key 和 ::value 都是当前的遍历数值
 
遍历数组示例:
- 遍历一个字符串数组 ["A", "B", "C", "D"]
 - 对每个元素调用 flows.处理数组元素 处理器
 - ::key 为当前索引,::value 为当前元素值
 
遍历对象示例:
- 遍历一个包含用户信息的对象
 - 对每个属性调用 flows.处理对象属性 处理器
 - ::key 为属性名,::value 为属性值
 
遍历结构体示例:
- 结构体会被转换为 Map 后进行遍历
 - 对每个字段调用 flows.处理结构体字段 处理器
 - ::key 为字段名,::value 为字段值
 
For 流程控制示例 
以下示例展示了如何使用 For 流程控制进行数值范围遍历:
json
{
  "label": "For流程控制示例",
  "version": "1.0.0",
  "description": "演示For流程控制的使用方法",
  "nodes": [
    {
      "name": "数值遍历",
      "process": "xiang.flow.For",
      "args": [
        0,
        5,
        {
          "process": "flows.处理数值",
          "args": ["::key", "::value"]
        }
      ]
    }
  ],
  "output": {
    "示例说明": "For流程控制会遍历从0到4(不包含5)的数值",
    "遍历变量": {
      "key": "当前遍历的索引值,如0,1,2,3,4",
      "value": "与key相同,值为当前遍历的索引值"
    }
  }
}在上面的示例中:
For 流程控制接收三个参数:
- 第一个参数:起始值(包含)
 - 第二个参数:结束值(不包含)
 - 第三个参数:处理器配置
 
示例将遍历 0 到 4 的数值:
::key和::value都是当前的遍历索引值- 对每个数值调用 flows.处理数值 处理器
 - 处理器会收到两个相同的参数,例如当遍历到 2 时,两个参数都是 2
 
实际应用场景:
- 批量处理固定数量的任务
 - 生成指定范围的数值序列
 - 执行特定次数的操作