我正在尝试创建一个Observable,在单击按钮时,它会发出PAGE_SIZE
的数组(第一次单击时应该发出[0, 1, 2, 3, 4]
),但要注意的是,在按钮之后单击一个间隔将开始发出更多与原始数字串联的数字(即,用户单击间隔后,应该发出[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
,然后发出[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
,依此类推。)
以下内容几乎可以满足我的要求,但是当用户再次单击该按钮时,我需要整个过程重新开始。
有什么想法吗?
const PAGE_SIZE = 5;
let currentPage = 0;
const buttonEl = document.getElementsByTagName('button')[0];
const refreshSource$ = new rxjs.Subject().pipe(rxjs.operators.concatMap(() => rxjs.interval(5000)));
const clickSource$ = new rxjs.fromEvent(buttonEl, 'click').pipe(rxjs.operators.tap(() => {
refreshSource$.next();
refreshSource$.complete();
}));
const clips$ = rxjs.merge(clickSource$, refreshSource$).pipe(rxjs.operators.mergeMap(value => {
if (value.type === undefined)
return makeObservable(value + 1);
else
return makeObservable(0);
}), rxjs.operators.scan((acc, value) => acc.concat(value)), rxjs.operators.startWith([]));
clips$.subscribe(value => {
console.log('clips$', value);
});
function makeObservable(page) {
return rxjs.of(d3.range(page * PAGE_SIZE, (page + 1) * PAGE_SIZE));
}
答案 0 :(得分:1)
您需要的是每次单击都将映射切换到新的可观察到的位置,从而重新开始生成数组:
import { interval, fromEvent } from 'rxjs';
import { switchMap, take, map } from 'rxjs/operators';
const buttonEl = document.getElementById('button');
const pagesize = 5;
fromEvent(buttonEl, 'click')
.pipe(
// restart counter on every click
switchMap(() =>
interval(500).pipe(take(5))
),
map(i => {
const max = (i+1) * pagesize;
return Array.from(Array(max).keys());
})
)
.subscribe(console.log);
(stackblitz:https://stackblitz.com/edit/rxjs-v85ctu?file=index.html)
有关switchMap运算符的完整参考,请参见:https://www.learnrxjs.io/operators/transformation/switchmap.html