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);