我有分页界面。给定起点,请求将生成结果列表和延续指示符。
我创建了一个observable,它是通过构造和平面映射一个读取页面的observable来构建的。此可观察对象的结果包含页面数据和要继续的值。我将数据和平面映射到订阅者。产生价值流。
为了处理分页,我为下一页的值创建了一个主题。它以初始值播种,然后每当我收到有效下一页的响应时,我会推送到页面主题并触发另一次读取,直到没有更多内容读取为止。
有没有更惯用的方法呢?
function records(start = 'LATEST', limit = 1000) {
let pages = new rx.Subject();
this.connect(start)
.subscribe(page => pages.onNext(page));
let records = pages
.flatMap(page => {
return this.read(page, limit)
.doOnNext(result => {
let next = result.next;
if (next === undefined) {
pages.onCompleted();
} else {
pages.onNext(next);
}
});
})
.pluck('data')
.flatMap(data => data);
return records;
}
答案 0 :(得分:3)
这是一种合理的方式。它有几个潜在的缺陷(根据您的使用情况,可能会或可能不会影响您):
this.connect(start)
this.connect(start)
的完成,并且observable似乎永远不会产生任何东西。 connect
来电。这不是一个真正的大问题,但通常当构建一个可观察的时候,人们应该尝试将一次性用品链接在一起,这样如果调用者取消订阅,它就可以正常清理。以下是修改后的版本:
this.connect
传递给观察者。Observable.create
创建一个 cold observable,只有当调用者实际订阅时才启动,因此没有机会错过初始页面值并停止流。this.connect
订阅一次性订阅与整体订阅一次性代码:
function records(start = 'LATEST', limit = 1000) {
return Rx.Observable.create(observer => {
let pages = new Rx.Subject();
let connectSub = new Rx.SingleAssignmentDisposable();
let resultsSub = new Rx.SingleAssignmentDisposable();
let sub = new Rx.CompositeDisposable(connectSub, resultsSub);
// Make sure we subscribe to pages before we issue this.connect()
// just in case this.connect() finishes synchronously (possible if it caches values or something?)
let results = pages
.flatMap(page => this.read(page, limit))
.doOnNext(r => this.next !== undefined ? pages.onNext(this.next) : pages.onCompleted())
.flatMap(r => r.data);
resultsSub.setDisposable(results.subscribe(observer));
// now query the first page
connectSub.setDisposable(this.connect(start)
.subscribe(p => pages.onNext(p), e => observer.onError(e)));
return sub;
});
}
注意:我之前没有使用过ES6语法,所以希望我没有弄乱任何东西。