在 Rxjs 6 中将以前的值作为数组发出?

Emit previous values as an array in Rxjs 6?

我需要一个 Observable,它发出一个包含最多 X 个值的先前值数组。

基本上,类似于 bufferCount() 除了我希望它立即发出并保留 运行 历史。

of(1,2,3,4,5,6,7,8,9).pipe(
   bufferHistory(3)  // <-- something like this
).subscribe(v => console.log(v));
// starts
// [1]
// [2,1]
// [3,2,1]
// [4,3,2]
// [5,4,3]
// [6,5,4]
// [7,6,5]
// [8,7,6]
// [9,8,7]
// competes

我找不到 Rxjs 6 的运算符来执行此操作,最接近的是 bufferCount() 但它会在每个数组发出后 重置

数组输出的顺序并不重要。它可以是 [3,2,1][1,2,3],因为这只是现在的语义。

您可以为此使用 scan

of(1, 2, 3, 4, 5, 6, 7, 8, 9).pipe(
  scan((acc, val) => {
    acc.unshift(val);
    acc.splice(3);
    return acc;
  }, [])
).subscribe(v => console.log(v));

// [1]
// [2,1]
// [3,2,1]
// [4,3,2]
// [5,4,3]
// [6,5,4]
// [7,6,5]
// [8,7,6]
// [9,8,7]

或者:

of(1, 2, 3, 4, 5, 6, 7, 8, 9).pipe(
  scan((acc, val) => {
    acc.push(val);
    return acc.slice(-3);
  }, [])
).subscribe(v => console.log(v));
// [1]
// [1,2]
// [1,2,3]
// [2,3,4]
// [3,4,5]
// [4,5,6]
// [5,6,7]
// [6,7,8]
// [7,8,9]

要达到预期结果,一种选择是使用 map

基于数字创建数组
import { of} from 'rxjs'; 
import {  map, bufferCount} from 'rxjs/operators';


of(1,2,3,4,5,6,7,8,9).pipe(
   map(x => Array.from(Array(x).keys(), n => n + 1).slice(-3))
).subscribe(v => console.log(v));

参考工作代码- https://stackblitz.com/edit/rxjs-gv8ok5?file=index.ts