# 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`时同样的方式来描述,直接根据下面的图得到结果
![](https://box.kancloud.cn/a76c432b4959359e7539fe889a410aee_530x211.png)
如果将示例中`soure`这个Observable中的`take`参数值改为`3`, 我们可以绘制下面
这个图。
![](https://box.kancloud.cn/df3c4a57adb07427922a233f5c3be5dc_527x307.png)
很直观可以得出参与`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`过后的结果,采用老办法,见图即可得到结果:
![](https://box.kancloud.cn/c3b85125063187aaa9ca1c84b90d1e56_265x160.png)
- 说明
- 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
- 开发遇到的问题