Rxjs 使用map函数中的Observable的上一个值
我有一个事件产生的图像列表流,如下所示:Rxjs 使用map函数中的Observable的上一个值,rxjs,observable,Rxjs,Observable,我有一个事件产生的图像列表流,如下所示: const imageSrcs$ = Rx.Observable.fromEvent($('#clicker'), 'click') .flatMap(() => this.imageService.getImagesForUser(userUid)) .scan((acc, cur) => acc.concat(cur), []) .startWith([]); imageService.getImagesForUser(us
const imageSrcs$ = Rx.Observable.fromEvent($('#clicker'), 'click')
.flatMap(() => this.imageService.getImagesForUser(userUid))
.scan((acc, cur) => acc.concat(cur), [])
.startWith([]);
imageService.getImagesForUser(userId)
从数据库中检索有限数量的图像并返回图像列表:
[
{
id: number,
timestamp: string,
...
},...
]
所以这个可观察的对象只是获取结果,并在其上应用累加器(scan()
)。但是,getImagesForUser
还需要一个额外的参数startAt
,它是开始检索的时间戳。在我的例子中,这应该是可观察对象返回的数组中最后一个图像的时间戳
当然,我可以这样做:
lastTimestamp;
...
const imageSrcs$ = Rx.Observable.fromEvent($('#clicker'), 'click')
.flatMap(() => this.imageService.getImagesForUser(userUid, this.lastTimestamp))
.scan((acc, cur) => acc.concat(cur), [])
.startWith([])
.subscribe(list => this.lastTimestamp = list[list.length - 1].timestamp);
但这看起来并不是真正的关注点分离,我很想知道我是否可以在一个可观察的物体上做到这一点。我认为这样做会奏效:
const imageSrcs$ = Rx.Observable.fromEvent($('#clicker'), 'click')
.startWith([])
.filter(val => Array.isArray(val))
.last()
.map(val => val[val.length - 1].timestamp)
.flatMap(startAt => this.imageService.getImagesForUser(userUid, startAt))
.scan((acc, cur) => acc.concat(cur), []);
当然,这不是因为点击事件被过滤掉了。我能想到的最简单的方法是这样的(这只是模拟您的用例,但我想您会明白这一点): 最后,
scan()
操作符也可以进入.defer()
回调中
我使用的是
Observable.timer(01000)
,而不是点击。我不知道是否有更好的方法来做到这一点,而不使用可观察链之外的任何状态变量。是的,我想这是最好的方法。我希望do的产品不会有副作用,但是哦,好吧,startAt
被包装在Observable中。推迟关闭,这样至少不会泄漏。
function getImagesForUser(startAt) {
return Observable
.range(startAt * 5, 5)
.toArray();
}
const imageSrcs$ = Observable.defer(() => {
let startAt = 0;
return Observable.timer(0, 1000)
.flatMap(() => getImagesForUser(startAt))
.do(arr => startAt = arr[arr.length - 1]);
})
.scan((acc, cur) => acc.concat(cur), [])
.startWith([])
.subscribe(console.log);