# 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 示例圖

大家有沒有發現這個很像一棵樹,如果我們把它的子節點都用線連接起來,會得出什么呢?

注意:這里我用不同顏色對每一個時間作了區分,首先在`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]。
反過來我們用這種方式來分析示例一和二的結果,就一目了然了。

直接可以看出結果:[0, 0], [1, 0], [1, 1], [2, 1], [2, 2], [2, 3], [2, 4]
- 說明
- angular 1.x
- ngModelController
- ngOptions
- ngModelOptions
- lifecycle
- directive
- angular 2
- @angular/forms
- 類
- AbstractControl
- AbstractControlDirective
- AbstractFormGroupDirective
- FormControl
- FormArray
- FormBuilder
- FormGroup
- NgControl
- 接口
- controlValueAccessor
- 指令
- DefaultValueAccessor
- Angular 2 生命周期
- OnInit
- DoCheck
- @angular/router
- 配置
- Routes
- 指令
- RouterOutlet
- RouterLink
- 接口
- ActivatedRoute
- UrlTree
- NavigationExtras
- ActivatedRouteSnapshot
- RouterStateSnapshot
- 類
- UrlSegment
- UrlSegmentGroup
- UrlSerializer
- DefaultUrlSerializer
- Router
- bug記得
- @angular/http
- 類
- Http
- Body
- Response
- ResponseOptions
- Header
- Request
- RequestOptions
- URLSearchParams
- @angular/core
- decorator
- Component-decorator
- animation
- DI
- linker
- TemplateRef
- ElementRef
- EmbeddedViewRef
- ViewRef
- ViewContainerRef
- Query
- ComponentFactory
- ComponentRef
- Renderer
- change_detection
- KeyValueDiffers
- IterableDiffers
- ChangeDetectorRef
- ChangeDetectionStrategy
- Zone
- ngZone
- @angular/common
- 指令
- NgTemplateOutlet
- QueryList
- bootstrap4
- card
- form
- 重點關注博客
- 學習過的文章
- 筆記
- Angular 2 雙向綁定
- 將字符串解析成DOM
- rx相關
- operators
- combineLatest
- combineAll
- concat(All, Map, *MapTo)
- 背壓(backpressure)
- js事件keycode對應表
- 裝飾器
- 有用的代碼摘錄
- 日期操作
- 數量操作
- 字符操作
- rxjs問題
- 小示例
- h5面試準備
- react
- 開發遇到的問題