当前工作代码
我有以下rxjs/Observable
:
findMessages(chatItem: any): Observable<any[]> {
return Observable.create((observer) => {
let processing: boolean = false;
this.firebaseDataService.findMessages(chatItem).forEach(firebaseItems => {
if (!processing) {
processing = true;
this.localDataService.findMessages(chatItem).then((localItems: any[]) => {
let mergedItems: any[] = this.arrayUnique(firebaseItems.concat(localItems), false);
mergedItems.sort((a, b) => {
return parseFloat(a.negativtimestamp) - parseFloat(b.negativtimestamp);
});
if (this.me && mergedItems && mergedItems[0] && this.me.uid === mergedItems[0].memberId2) {
this.updateChatWithMessage(chatItem, mergedItems[0], false);
}
observer.next(mergedItems);
processing = false;
});
}
});
});
}
和
this.firelist = this.dataService.findMessages(this.chatItem);
this.firelist.subscribe(items => {
...
});
如您所见,它会返回firebaseItems
和localItems
的列表,这些列表将合并到mergedItems
。这非常有效。
效果提升
但是,我正在尝试提高项目加载的性能。所以,我想首先加载localItems
,然后使用firebaseItems
添加到列表中。
所以我尝试添加以下功能:
findLocalMessages(chatItem: any): Observable<any[]> {
return Observable.create((observer) => {
this.localDataService.findMessages(chatItem).then((localItems: any[]) => {
localItems.sort((a, b) => {
return parseFloat(a.negativtimestamp) - parseFloat(b.negativtimestamp);
});
observer.next(localItems);
});
});
}
并按如下方式调用:
this.firelist = this.dataService.findLocalMessages(this.chatItem);
this.firelist = this.dataService.findMessages(this.chatItem);
this.firelist.subscribe(items => {
...
});
问题
现在已经引入了一个错误,现在有2个Observables
并且结果不符合预期。排序顺序不正确,某些项目由于某种原因未添加到this.firelist
。
问题
最好的办法是什么?
我在想是否有可能让findLocalMessages
Observable
只被解雇一次,然后它就再也无法工作了findMessages
Observable
将保持清单。这可能吗?我一直在关注Observable
api,似乎无法弄清楚如何做到这一点。
任何帮助表示赞赏。
答案 0 :(得分:2)
由于存在过度简化问题陈述的风险,您需要以有效的方式合并和排序两个数据流。
你所做的分离是朝着正确方向迈出的一步。 你没有得到所有消息的原因是你用第二个覆盖了第一个observable。看看下面的例子,看看如果你尝试将第二个observable分配给move而不是move2会发生什么。
let move = Observable.fromEvent(document.getElementById("1"), 'mousemove');
let move2 = Observable.fromEvent(document.getElementById("2"), 'mousemove');
move
.subscribe((event:any) => {
if (event) {
console.log(event.path[0].id)
}
});
move2
.subscribe((event:any) => {
if (event) {
console.log(event.path[0].id)
}
});
<h1>
<div id="1">
aaaaaaaaaaaaaaaaaaaaaaaaa
</div>
<div id="2">
bbbbbbbbbbbbbbbbbbbbbbbbb
</div>
</h1>
为了正确合并两个流,您需要使用merge operator,如下所示:
let move = Observable.fromEvent(document.getElementById("1"), 'mousemove');
let move2 = Observable.fromEvent(document.getElementById("2"), 'mousemove');
move.merge(move2)
.subscribe((event:any) => {
if (event) {
console.log(event.path[0].id)
}
});
现在你需要做的就是对它们进行排序。我建议你只在合并之后进行排序,否则,你最终会得到两个本地排序的流,而不是全局排序。