Javascript Observable性能问题

时间:2017-06-29 07:55:02

标签: javascript rxjs observable

当前工作代码

我有以下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 => {
    ...
});

如您所见,它会返回firebaseItemslocalItems的列表,这些列表将合并到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,似乎无法弄清楚如何做到这一点。

任何帮助表示赞赏。

1 个答案:

答案 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)
              }
          });

现在你需要做的就是对它们进行排序。我建议你只在合并之后进行排序,否则,你最终会得到两个本地排序的流,而不是全局排序。