RxJs SwitchMapTo 操作符之移花接木

将每个源值投影到同一个 Observable,该 Observable 在输出 Observable 中使用 switchMap 多次展平。

输入一个 Observable,输出一个 function Operator. 实际是一个函数,每次在源 Observable 上发出值时,该函数都会返回一个 新的 Observable.

该函数从给定的 innerObservable 发出项目,并且仅从最近投影的内部 Observable 中获取值。

看个例子:

import { EMPTY, range } from 'rxjs';
import { first, take, tap } from 'rxjs/operators';

import { fromEvent, interval } from 'rxjs';
import { switchMapTo } from 'rxjs/operators';

const clicks = fromEvent(document, 'click');

const test = event => console.log('Jerry: ', event);
const result = clicks.pipe(
  tap(test),

  switchMapTo(interval(1000))
);
result.subscribe(x => console.log(x));

输出:

每次点击之后,click$ 抛出的 PointerEvent,被 switchMapTo 返回的 Function Operator 丢弃了。最后用户订阅 result 函数里,打印的值,是 switchMapTo 输入的 interval(1000) Observable 发射的值,而不再是 clicks$ 抛出的 PointerEvent.

再看另一个在网页显示倒计时数字的例子。

import './style.css';

import { interval, fromEvent } from 'rxjs';
import {
  switchMapTo,
  scan,
  startWith,
  takeWhile,
  finalize
} from 'rxjs/operators';

const COUNTDOWN_TIME = 10;

// reference
const countdownElem = document.getElementById('countdown');

// streams
const click$ = fromEvent(document, 'click');
const countdown$ = interval(2000).pipe(
  scan((acc, _) => --acc, COUNTDOWN_TIME),
  startWith(COUNTDOWN_TIME)
);

click$
  .pipe(
    switchMapTo(countdown$),
    takeWhile(val => val >= -10),
    finalize(() => (countdownElem.innerHTML = "We're done here!"))
  )
  .subscribe((val: any) => (countdownElem.innerHTML = val));

初始整数是10,每隔2秒钟减一,减到 -10 时停止。

思路:触发计数器开始递减的操作是点击屏幕,因此需要使用 fromEvent 来构造 Observable :click$

每隔两秒钟执行某项操作,因此需要用 interval 构造第二个 Observable.

一旦计数器启动之后,每隔两秒钟需要执行递减操作,因此需要用 switchMapTo,将 click$ 映射成 interval Observable.

之后的值传递,就和 click$ 再无任何关联了。

因为是递减操作,暗示这是一个 stateful 场景,故选用 scan 操作符维护内部状态。

(0)

相关推荐

  • Webpack 5模块联邦会不会引发微前端的革命呢? 本文详解

    Webpack 5的模块联邦提供加载部分编译好的代码能力,这个似乎会成为微前端架构的标准实现. Webpack只是我分享的一小点,我是08年出道的高级前端架构师,有问题或者交流经验可以进我的扣扣裙 5 ...

  • RxJS快速入门

    内容导航 目录 内容导航 RxJS是什么 RxJS的主要成员 Observable (可观察对象) 创建 Observable 订阅 Observables 执行 Observables 清理 Obs ...

  • Rxjs debounce 操作符在 SAP Spartacus 函数节流中的一个实际使用例子

    在 window-ref.ts 的实现里,定义了一个每隔 300 毫秒,通过 fromEvent 发射一个 resize event 的Observable: /** * Returns an obs ...

  • C#深入浅出之操作符和控制流程

    操作符 操作符简单举例就是生活中的+-*/等等运算符号,下面会详细讨论运算符内容. 一元正负操作符 有时候需要改变数值的正负号.一元操作符(-)可以使得数字的正负号改变. 例如: int a = -1 ...

  • 为了省钱!小气所长逼我自创【移花接木式】效果图!!

    小气的所长大人不肯花钱做效果图 非逼着让我学 要求还贼高 不得已打出一套[移花接木式]PS效果图做法 [全流程]快速演示 01 移花接木大法 首先我们准备好[场景意向图]和[建筑素模] 建筑的视角最好 ...

  • 花卉摄影中的“移花接木”法

    北方早春开的花,比如杏花.桃花.榆叶梅等,期初都与"干枝梅"类似,树上只有花,没有或者很少有叶子,看起来既热闹又单调,学摄影很久的人,早已不满足于标本式的写实拍花,本文就向您介绍& ...

  • RxJs fromEvent 工作原理分析

    fromEvent(this.test, 'click').subscribe((event) => console.log(event)); this.test 的赋值逻辑: this.tes ...

  • RxJs map operator 工作原理分析

    使用一个例子来研究 map 操作符的工作原理. 推荐阅读本文之前,先浏览这篇文章RxJs fromEvent 工作原理分析以了解相关知识. 源代码: import { Component, OnIni ...

  • 《移花接木》

    世人多会移花接木,见者心生怜悯.         我们需要三思而后行,移花接木者多,行路定当小心.曾经我们慢慢生活,一点一点享受时光,怎料世事难料,你我总会遇到令人发指之事,令人难为情之事,令人窘迫之 ...

  • 中考作文如何移花接木,一篇多用?​

    很多同学都会提前准备几篇作文来应考,这其实已是公开的秘密.这种做法是一种微观视角下的现实主义,无可厚非.不过,移花接木一定要注意技巧,否则被老师判断为宿构或抄袭,分数就不会高了. 中考命题以记叙文为主 ...

  • Rxjs Observable.pipe 传入多个 operators 的执行逻辑分析

    测试代码: fromEvent(this.test, 'click').pipe(map( event => event.timeStamp), mapTo(1)).subscribe((eve ...