# combineAll
通過等待外部Observable完成,然后應用`combineLatest`,將高階Observable轉換成一階Observable。
**方法簽名**:
```
public combineAll(project: function): Observable
```
**示例一**:
```javascript
var source = Rx.Observable.interval(1000).take(2);
var example = source
.map(val => Rx.Observable
.interval(1000)
.map(i => `${val}: ${i}`)
.take(5)
);
var combined = example.combineAll();
combined.subscribe(console.log);
```
**結果**:
```
["0: 0", "1: 0"]
["0: 1", "1: 0"]
["0: 1", "1: 1"]
["0: 2", "1: 1"]
["0: 2", "1: 2"]
["0: 3", "1: 2"]
["0: 3", "1: 3"]
["0: 4", "1: 3"]
["0: 4", "1: 4"]
```
**分析**:在調用`combineAll`時,內部Observable(`source`執行`map`時返回的)會等待外部Obserevable完成,這里當`source`發出值`0`, `1`后,開始執行內部Observable。由于外部發出了2個值,所以會得到一個長度為2的數組,當`val`值為`0`時并執行完`take`后我們得到[0, 0], [0, 1], [0, 2], [0, 3], [0, 4]這樣一個結果,然后`val`值為`1`時,得到[1,0], [1,1], [1,2], [1,3], [1,4]。然后對兩次獲得的結果執行`combineLatest`。
整個過程可以參照分析`combineLatest`時同樣的方式來描述,直接根據下面的圖得到結果

如果將示例中`soure`這個Observable中的`take`參數值改為`3`, 我們可以繪制下面
這個圖。

很直觀可以得出參與`combineLatest`計算前的3個Observable的結果, 這里假定為`A`, `B`, `C`。那么`A`為
`[0, 0], [0, 1], [0, 2], [0, 3], [0, 4]`,`B`為`[1, 0], [1, 1], [1, 2], [1, 3], [1, 4]`, `C`為`[2, 0], [2, 1], [2, 2], [2, 3], [2, 4]`,然后我們以這些結果值為樹節點,順序構造出上面的分析樹。
,
對于節點`0,0`,很顯然只有一條路徑`[0, 0], [1, 0], [2, 0]`, 對于后面的節點都有3條路徑,這里直接給出后面的結果:
```
[0, 1], [1, 0], [2, 0]
[0, 1], [1, 1], [2, 0]
[0, 1], [1, 1], [2, 1]
[0, 2], [1, 1], [2, 1]
[0, 2], [1, 2], [2, 1]
[0, 2], [1, 2], [2, 2]
[0, 3], [1, 2], [2, 2]
[0, 3], [1, 3], [2, 2]
[0, 3], [1, 3], [2, 3]
[0, 4], [1, 4], [2, 3]
[0, 4], [1, 4], [2, 4]
```
**示例二**
```javascript
var clicks = Rx.Observable.fromEvent(document, 'click');
var higherOrder = clicks.map(ev =>
Rx.Observable.interval(Math.random()*2000).take(3)
).take(2);
var result = higherOrder.combineAll();
result.subscribe(x => console.log(x));
```
> 注:來自rxjs官網[示例](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-combineAll)
這個例子得到的結果有可能為
```
[0, 2]
[1, 2]
[2, 2]
```
或者:
```
[0, 0]
[1, 0]
[1, 1]
[2, 1]
[2, 2]
```
這是因為傳給`Rx.Observable.interval`的參數是一個隨機數造成的,我們這里把它的參數直接改成`1000`方便分析結果。此時再次運行,會得到上面的第2個結果,為什么呢?
也許看了這個示例會有所疑問:
> 這個例子和示例一很相似,外層Observable發出2個值, 內部Observable發出3個值,結果應該類似`[0, 0], [0, 1]`這種才對呀?
其實,我們注意到鼠標點擊事件對象`ev`的值我們并沒有使用,由于`combineAll`內部調用`combineLatest`前,`map`函數執行后實際得到兩個一樣的結果:[0, 1, 2]。既然得到執行`map`過后的結果,采用老辦法,見圖即可得到結果:

- 說明
- 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
- 開發遇到的問題