RxJS takeWhile但包括最后一个值

Fan*_*Lin 18 reactive-programming rxjs rxjs5

我有一个RxJS5管道看起来像这样

Rx.Observable.from([2, 3, 4, 5, 6])
  .takeWhile((v) => { v !== 4 })
Run Code Online (Sandbox Code Playgroud)

我想保留订阅,直到我看到4,但我想最后一个元素4也包含在结果中.所以上面的例子应该是

2, 3, 4
Run Code Online (Sandbox Code Playgroud)

但是,根据官方文件,takeWhile运营商不具备包容性.这意味着当遇到与我们给出的谓词不匹配的元素时,它会在没有最后一个元素的情况下立即完成流.结果,上面的代码实际上会输出

2, 3
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,我能实现的最简单方法是什么,takeWhile但也用RxJS发出最后一个元素?

mar*_*tin 24

已经打开的PR添加了一个可选takeWhile(predicate, true)参数inclusive:https://github.com/ReactiveX/rxjs/pull/4115

至少有两种可能的解决方法:

  1. 使用takeWhile:

    of('red', 'blue', 'green', 'orange').pipe(
      concatMap(color => {
        if (color === 'green') {
          return of(color, null);
        }
        return of(color);
      }),
      takeWhile(color => color),
    )
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用concatMap():

    of('red', 'blue', 'green', 'orange').pipe(
      multicast(
        () => new ReplaySubject(1),
        subject => subject.pipe(
          takeWhile((c) => c !== 'green'),
          concat(subject.take(1),
        )
      ),
    )
    
    Run Code Online (Sandbox Code Playgroud)

我一直在使用这个运算符,所以我把它发给了我自己的一组额外的RxJS 5运算符:https://github.com/martinsik/rxjs-extra#takewhileinclusive

此RxJS 5问题中也讨论了此运算符:https://github.com/ReactiveX/rxjs/issues/2420

2019年1月:更新了RxJS 6


Bat*_*ato 13

更新 2019 年 3 月,rsjx版本6.4.0takeWhile最后有一个可选inclusive参数,允许保留破坏条件的第一个元素。所以现在的解决方案是简单地将true作为第二个参数传递takeWhile

import { takeWhile } from 'rxjs/operators';
import { from } from 'rxjs';

const cutOff = 4.5
const example = from([2, 3, 4, 5, 6])
.pipe(takeWhile(v => v < cutOff, true ))
const subscribe = example.subscribe(val =>
  console.log('inclusive:', val)
);
Run Code Online (Sandbox Code Playgroud)

输出:

inclusive: 2
inclusive: 3
inclusive: 4
inclusive: 5
Run Code Online (Sandbox Code Playgroud)

住在这里:

https://stackblitz.com/edit/typescript-m7zjkr?embed=1&file=index.ts

请注意,5 是第一个破坏条件的元素。请注意,endWith当您有动态条件(例如v < cutOff,您不知道最后一个元素是什么)时,这并不是真正的解决方案。

感谢@martin 指出这个拉取请求的存在。