用forkJoin进行条件可观察

时间:2018-09-12 14:21:28

标签: javascript angular typescript rxjs observable

在某些情况下,我可能需要或不需要将可观察对象添加到列表中。然后,我想forkJoin我拥有的可观察对象,以便一旦所有数据可用就可以加载页面。

let observables: Observable<any>[] = [];

observables.push(this.taskService.getStep(this.housingTransactionId, this.task.stageReferenceId, this.task.stepReferenceId));

if (this.task.associatedChatThreadId) {
    observables.push(this.messageHubService.getChatThread(this.housingTransactionId, this.task.associatedChatThreadId));
}

if (this.task.associatedDocuments && this.task.associatedDocuments.length > 0) {
    this.task.associatedDocuments.forEach(documentId => {
        observables.push(this.documentHubService.getDocumentProperties(this.housingTransactionId, documentId));
    });
}

Observable.forkJoin(observables)
    .subscribe(([step, chatThread, ...documents]) => {

        this.step = step;           
        this.chatThread = chatThread;           
        this.documents = documents;

        this.isPageLoading = false;

    }, error => {
        this.isPageLoading = false;
        console.log(error);
    });

我遇到的问题是,如果我没有this.task.associatedChatThreadId,那么可观察对象将不会添加到列表中,并且在执行forkJoin时,...documents在subscription方法中的chatThread属性的位置(当然,第一个文档!)。

是否有办法确保来自forkJoin的响应的位置?还是我/我可以使用其他方法?

2 个答案:

答案 0 :(得分:4)

如果不满足条件,可以很容易地添加值为Observable.of(null)的哑null,以保持相同的响应顺序:

if (this.task.associatedChatThreadId) {
    observables.push(this.messageHubService....);
} else {
    observables.push(Observable.of(null))
}

然后在订阅中,您可以检查chatThread === null是否因为它总是存在于同一位置。

或者,您可以在observables中用一些额外的对象包装每个Observable,这将使它在订阅服务器中唯一可识别,但不必要地变得复杂,因此我个人会坚持第一种选择。

答案 1 :(得分:0)

另一种方法是不使用民谣加入,而是单独订阅。同时,使isPageLoading一个BehaviorSubject计数您当前有多少个异步请求。每次发出请求时,完成请求时都可以拥有isPageLoading.next(1)和isPageLoading.next(-1)。