目录

组合

优质
小牛编辑
123浏览
2023-12-01

组合变换是一组多元变换形式,每次变换是由多个节点出发,经过相互计算最终向其下游节点进行传播。在实现的过程中,通常需要借助一个对象把多个变换管理起来,例如源码中的 EasyReact/Core/NodeTransforms/EZRCombineTransformGroup.h。下面介绍下全部的组合变换形式。

combine

响应式编程经常会使用 a := b + c 来举例,意图是当 b 或者 c 的值发生变化的时候,a 会保持两者的加和。那么在响应式库 EasyReact 中,我们是怎样体现的呢?就是通过 EZRCombine-mapEach 操作:

EZRMutableNode<NSNumber *> *nodeA = [EZRMutableNode value:@1];
EZRMutableNode<NSNumber *> *nodeB = [EZRMutableNode value:@2];
EZRNode<NSNumber *> *nodeC = [EZRCombine(nodeA, nodeB) mapEach:^NSNumber *(NSNumber *a, NSNumber *b) {
  return @(a.integerValue + b.integerValue);
}];

nodeC.value;  // <- 1 + 2 = 3
nodeA.value = @4;
nodeC.value;  // <- 4 + 2 = 6
nodeB.value = @6;
nodeC.value;  // <- 4 + 6 = 10

merge

合并操作其实很好理解,合并多个节点作为上游,当任何一个节点有新值的时候,下游都会更新:

EZRMutableNode<NSNumber *> *nodeA = [EZRMutableNode value:@1];
EZRMutableNode<NSNumber *> *nodeB = [EZRMutableNode value:@2];
EZRNode<NSNumber *> *nodeC = [nodeA merge:nodeB];

// 首次合并会以最后有值的节点的值作为下游节点的初始值
nodeC.value;                                                  // <- 2
nodeA.value = @3;
nodeC.value;                                                  // <- 3
nodeB.value = @4;
nodeC.value;                                                  // <- 4

zip

拉链操作是这样的一种操作:它将多个节点作为上游,所有的节点的第一个值放在一个元组里,所有的节点的第二个值放在一个元组里……以此类推,以这些元组作为值的就是下游。它就好像拉链一样一个扣着一个:

EZRMutableNode<NSNumber *> *nodeA = [EZRMutableNode value:@1];
EZRMutableNode<NSNumber *> *nodeB = [EZRMutableNode value:@2];
EZRNode<EZTuple2<NSNumber *, NSNumber *> *> *nodeC = [nodeA zip:nodeB];

[[nodeC listenedBy:self] withBlock:^(EZTuple2<NSNumber *, NSNumber *> *tuple) {
  NSLog(@"接收到 %@", tuple);
}];
nodeA.value = @3;
nodeA.value = @4;
nodeB.value = @5;
nodeA.value = @6;
nodeB.value = @7;
/* 打印如下:
接收到 <EZTuple2: 0x60800002b140>(
  first = 1;
  second = 2;
  last = 2;
)
接收到 <EZTuple2: 0x60800002ac40>(
  first = 3;
  second = 5;
  last = 5;
)
接收到 <EZTuple2: 0x600000231ee0>(
  first = 4;
  second = 7;
  last = 7;
)
 */

其过程如下:

nodeA:  -------1-------3-------4---------------6
               |        ╲        ╲
               |          ╲          ╲
               |            ╲            ╲
               |              ╲              ╲
nodeB:  -------2-----------------+-----5--------+------7
               |                   ╲   |          ╲    |
               ↓                     ↘ ↓            ↘  ↓
nodeC:  -----(1,2)-------------------(3,5)-----------(4,7)