🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# combineLatest 组合多个Observables以创建一个Observable, 并根据每个输入的Observable的最新值计算。 **方法签名**: ``` // 静态方法 public static combineLatest(observable1: ObservableInput, observable2: ObservableInput, project: function, scheduler: Scheduler): Observable // 实例方法 public combineLatest(other: ObservableInput, project: function): Observable ``` > 注意:这个方法可以同时作为Observable的静态方法和实例方法使用 - **示例一:使用实例方法** ```javascript var source = Rx.Observable.interval(1000).take(3); var dist = Rx.Observable.interval(1000).take(5); var r = source.combineLatest(dist, (s, d) => `source: ${s} and dist: ${d}`); r.subscribe(console.log); ``` - **示例二:使用静态方法** ```javascript var source = Rx.Observable.interval(1000).take(3); var dist = Rx.Observable.interval(1000).take(5); var r = Rx.Observable.combineLatest(source, dist, (s, d) => `source: ${s} and dist: ${d}`) // or `Rx.Observable.combineLatest([source, dist], (s, d) => `source: ${s} and dist: ${d}`)` r.subscribe(console.log); ``` 上述两个示例的结果都为: ``` source: 0 and dist: 0 source: 1 and dist: 0 source: 1 and dist: 1 source: 2 and dist: 1 source: 2 and dist: 2 source: 2 and dist: 3 source: 2 and dist: 4 ``` 下面分析一下为什么会得到上述结果 ,以`combineLatest`实例方法为例。每当Observable发出值时,它会从每个Observable收集最新的值组成数组(这里数组长为2),这里`source`发出了3个值`0`, `1`, `2`,`dist`发出了`0`, `1`, `2`, `3`, `4`。 ``` source:-- 0 - 1 - 2| -- combineLatest() dist: -- 0 - 1 - 2 - 3 - 4| -- ``` 如果`source`和`dist`都发出5个值,那么结果如下: ``` source = 0, dist = [0] # 第1秒 source = 1, dist = [0, 1] # 第2秒 source = 2, dist = [1, 2] # 第3秒 source = 3, dist = [2, 3] # 第4钞 source = 4, dist = [3, 4] # 第5钞 ``` 由于`source`在3秒过后就停止了,而`dist`还在继续执行,此时dist的值为从`source`结束到`dist` 结束这段区间`dist`最后发出的值,即: `source = 2, dist = [1, 2, 3, 4] # 第3秒` **示例三:组合多个Observable** ```javascript // 1秒过后发出第一个值,然后每隔4秒发出下一个值 var timerOne = Rx.Observable.timer(1000, 4000); // 2秒过后发出第一个值,然后每隔4秒发出下一个值 var timerTwo = Rx.Observable.timer(2000, 4000); // 3秒过后发出第一个值,然后每隔4秒发出下一个值 var timerThree = Rx.Observable.timer(3000, 4000); var combined = Rx.Observable.combineLatest( timerOne, timerTwo, timerThree ); var subscribe = combined.subscribe(latestValues => { var [one, two, three] =latestValues; console.log(`one: ${one}, two: ${two}, three: ${three}`); }); ``` **结果**: ``` one: 0, two: 0, three: 0 one: 1, two: 0, three: 0 one: 1, two: 1, three: 0 one: 1, two: 1, three: 1 one: 2, two: 1, three: 1 one: 2, two: 2, three: 1 one: 2, two: 2, three: 2 one: 3, two: 2, three: 2 one: 3, two: 3, three: 2 one: 3, two: 3, three: 3 one: 4, two: 3, three: 3 one: 4, two: 4, three: 3 one: 4, two: 4, three: 4 one: 5, two: 4, three: 4 one: 5, two: 5, three: 4 one: 5, two: 5, three: 5 // ... ``` 下面是一个根据时间顺序所画的一个示例 marble 示例图 ![](https://box.kancloud.cn/d30a20a9b5e0c38264ca09887bea6f16_866x160.png) 大家有没有发现这个很像一棵树,如果我们把它的子节点都用线连接起来,会得出什么呢? ![](https://box.kancloud.cn/d02c57a797d18f553868fabb6cb4cf11_866x160.png) 注意:这里我用不同颜色对每一个时间作了区分,首先在`0`节点这颗树,只有一个路径,即: [0, 0, 0], 然后是`1`这棵树,它的路径有,[1, 0, 0], [1, 1, 0], [1, 1, 1], 如果对比上面的结果可以发现,刚好和输出一致。 接着看`2`这棵树,可以直接写出结果[2, 1, 0], [2, 1, 1], [2, 2, 1], [2, 2, 2],但有一点需要注意的是[2, 1, 0]这个路径是不合法的,因为它不属于最近一次发出的值,所以`3`这棵树的结果不包括[3, 2, 1]路径,`4`这棵树不包括[4, 3, 2]。 反过来我们用这种方式来分析示例一和二的结果,就一目了然了。 ![](https://box.kancloud.cn/7ab24d5e6a6a4e36f9756035637f6d3a_357x145.png) 直接可以看出结果:[0, 0], [1, 0], [1, 1], [2, 1], [2, 2], [2, 3], [2, 4]