CombineLatest 的使用场景:

This operator is best used when you have multiple, long-lived observables that rely on each other for some calculation or determination.

当有多个长时间存活的 Observable,且依赖彼此,共同完成某些计算逻辑时,适合使用 CombineLatest.

When any observable emits a value, emit the last emitted value from each.

为了学习 CombineLatest 的用法,我写了下面这个小程序:

import { Component, OnInit, Inject } from '@angular/core';
import { fromEvent, combineLatest } from 'rxjs';
import { mapTo, startWith, scan, tap, map } from 'rxjs/operators';
import { DOCUMENT } from '@angular/common';@Component({selector: 'app-combine-latest',templateUrl: './combine-latest.component.html'
})
export class CombineLatestComponent implements OnInit {readonly document: Document;constructor(// https://github.com/angular/angular/issues/20351@Inject(DOCUMENT) document: any) {this.document = document as Document;}redTotal:HTMLElement;blackTotal: HTMLElement;total:HTMLElement;  test:HTMLElement;ngOnInit(): void {this.redTotal = this.document.getElementById('red-total'); this.blackTotal = this.document.getElementById('black-total');this.total = this.document.getElementById('total');this.test = this.document.getElementById('test');combineLatest(this.addOneClick$('red'), this.addOneClick$('black')).subscribe(([red, black]: any) => {this.redTotal.innerHTML = red;this.blackTotal.innerHTML = black;this.total.innerHTML = red + black;});fromEvent(this.test, 'click').pipe(map( event => event.timeStamp), mapTo(1)).subscribe((event) => console.log(event));}addOneClick$ = id =>fromEvent(this.document.getElementById(id), 'click').pipe(// map every click to 1mapTo(1),// keep a running totalscan((acc, curr) => acc + curr, 0),startWith(0));
}

效果:

  • 点击 Red 按钮,则 Red 计数器 和 Total 计数器 加 1
  • 点击 Black 按钮,则 Black 计数器 和 Total 计数器 加 1

combine 输入参数:两个 Observable:

我这个例子里,只执行下面这行语句,其他 IF 分支都没有进去:

return fromArray(observables, scheduler).lift(new CombineLatestOperator(resultSelector))

首先执行 fromArray:输入是 Array,包含两个元素:

fromArray: 返回一个新的 Observable,输入是subscribeToArray(input).

关于 subscribeToArray 的逻辑分析,参考我这篇文章:Rxjs 里 subscribeToArray 工具函数的详细分析.

下一步实例化 CombineLatestOperator:

执行 lift 操作,创建新的 Observable 对象:

应用程序调用 Observable 对象的 subscribe 方法:

闭包里包含的两个 Observable,分别 for red 和 black 按钮:

顺着 Observable 的 source 属性和 _subscribe, 能找到 该 Observable pipe 里传递的所有操作:

首先使用 array 的第一个元素作为参数,调用 subscriber 函数:

先执行 mapTo(1) 逻辑:

Maptosubscriber 的 destination 指向 Scansubscriber:

scan.js 的内部实现:

accumulator 就是应用程序自定义的函数:

其中 acc 就是 scan.js 里的 seed,而 curr 即是当前值。

当前这轮迭代的结果存入 Scan Operator 的 seed 字段里,作为下一次迭代的输入:

这种 Operator 的实现都有套路:

  1. export 的 function,就是传入 Observable.pipe 里的代码:

  1. operator 实现的 call 函数
  2. ScanSubscriber 继承了 Subscriber,重新实现了 _next 方法。不同的 subscriber,差异就体现在这些 _next 方法上。

点击 red 或者 black 按钮后,两个 Observable 的初始值:0,0:

这个0,0 是怎么生成的?
两个空的对象:NONE

是在这里插入的:

这个 merge map 应该是框架自动生成的:

第一个元素已经从空对象转换成了0:

这行语句执行完之后,就变成两个 0 了:

使用 slice API 将数组复制一份:

由此可见,combineLatest Operator 本身不维护状态,而是等待维护状态的 scan 的输入:

更多Jerry的原创文章,尽在:“汪子熙”:

RxJS CombineLatest operator 的一个具体使用例子相关推荐

  1. RxJs combineLatest Operator 的数组用法

    第一种写法: import { Component, OnInit, Inject } from '@angular/core'; import { fromEvent, combineLatest ...

  2. 多态性与虚拟函数一个典型的例子第一步

    **#include <iostream> #include <strings.h> #include <cstring>using namespace std; ...

  3. ​【Python基础】告别枯燥,60 秒学会一个 Python 小例子(文末下载)

    本文推荐一个python的傻瓜式的学习资源,内容简单易懂,让人可以在60 秒学会一个 Python 小例子 当前库已有 300多 个实用的小例子 本文来源:https://github.com/jac ...

  4. 类模板与运算符重载(一个简单的例子)

    类模板与运算符重载(一个简单的例子) 标签(空格分隔): C++ 算法竞赛 下面是一段简单的代码,表示我们建立了一个类模板Vector,可以看做是对STL中vector的简单实现. 为了让这个Vect ...

  5. 抽象语法树 c语言,一个简单的例子看懂抽象语法树的魔力

    在计算机科学中,抽象语法树(Abstract Syntax Tree,AST),或简称语法树(Syntax tree),是源代码语法结构的一种抽象表示.它以树状的形式表现编程语言的语法结构,树上的每个 ...

  6. 一个简单的例子学会github repository的webhook

    2019独角兽企业重金招聘Python工程师标准>>> github的webhook是个有用的功能,允许开发人员指定一个服务器的url.当开发者对github仓库施加操作,比如提交代 ...

  7. .net中的对象序列化(1): 序列化是什么, 以及一个简单的例子

    1. 为什么需要序列化,什么是序列化 对于一个程序来说, 使用到的对象都是存在于内存中的.如果想保存这些对象的运行时状态, 或者需要在不同进程或者网络间传递对象,就需要序列化. 序列化就是讲运行中的对 ...

  8. 一个具体的例子学习Java volatile关键字

    相信大多数Java程序员都学习过volatile这个关键字的用法.百度百科上对volatile的定义: volatile是一个类型修饰符(type specifier),被设计用来修饰被不同线程访问和 ...

  9. 一个简单的例子看java线程机制

    一个简单的例子看java线程机制 作者: zyf0808 发表日期: 2006-03-26 11:20 文章属性: 原创 复制链接 import java.util.*; public class T ...

最新文章

  1. AngularJS学习笔记之一: AngularJS入门
  2. Python 能做什么?
  3. 华为MSTP配置教程(二)
  4. 优化 bulk insert
  5. TensorFlow全新的数据读取方式:Dataset API入门教程
  6. OpenCV Lucas-Kanade光流的实例(附完整代码)
  7. 认识代码编辑区域与解决方案区域 005
  8. 《Photoshop混合模式深度剖析》目录—导读
  9. 它在计算机房的旁边英文,计算机房设备搬迁协议 (中英文)
  10. C++之const关键字探究
  11. nginx nodejs环境配置_Linux基本开发环境配置git,c++,nodejs,nginx
  12. 2. PHP 自动转义函数
  13. Cocos Creator制作一个虚拟摇杆
  14. 前端怎么加粗字体_价值上百万美元又备受争议的微软雅黑正常大小+小字体
  15. Windows安装镜像下载
  16. PPT画成这样,述职答辩还能过吗?
  17. 亚马逊云科技——户外广告传媒行业数字化转型的摆渡者
  18. 服务器硬盘rad技术,服务器硬盘RAD选用.doc
  19. 产品经理到底是做什么的?|️ 什么是产品经理?
  20. Unbuntu远程电脑死机怎么解决

热门文章

  1. 鼠标形状 - - -放大镜 五指小手
  2. 天了噜,Java 8 要停止维护了!
  3. iOS 仿支付宝刮刮乐效果
  4. Linux操作系统下实现远程开机
  5. Centos6.5部署大众点评CAT
  6. (转)OOP(面向对象编程)的几大原则
  7. linux 系统如何防止攻击
  8. 2012年第一篇博文——致谢:2011年中国IT十大杰出博客获奖感言
  9. java实现多线程的4种方式
  10. (网页)parseFloat在工作中遇到的错误