代码之家  ›  专栏  ›  技术社区  ›  Chris

带forkJoin的条件可观测

  •  0
  • Chris  · 技术社区  · 8 年前

    我有一个例子,在这个例子中,我可能需要也可能不需要向列表中添加可观察对象。那么我想 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 ,则不将可观察对象添加到列表中 叉形连接 ...documents 处于 chatThread subscribe方法中的属性(第一个文档!)。

    有没有一种方法可以确保客户的响应定位 ? 或者我应该/我可以使用不同的方法吗?

    3 回复  |  直到 8 年前
        1
  •  9
  •   martin    8 年前

    最简单的是你可以加一个哑巴 Observable.of(null) null 如果不满足条件以保持相同的响应顺序,则返回值:

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

    chatThread === null 因为它总是出现在同一个位置。

    或者,您可以将每个可观察到的 observables

        2
  •  0
  •   Q. Liu    8 年前

    另一种方法是不使用folkJoin,而是单独订阅。同时,使isPageLoading成为一个BehaviorSubject,它统计当前有多少异步请求。每次提出请求时,您都可以isPageLoading.next文件(1) ,和isPageLoading.next文件(-1)当您完成请求时。

        3
  •  0
  •   tom van green    8 年前

    您可以创建一个helper函数,该函数接受具有字符串键和可观察值的对象,并返回一个可观察值,该对象将发出具有相同键的对象,但具有结果值而不是作为值的可观察值。

    我并不是说这是一个比martin建议的使用(null)更干净的版本,但它可能是一个替代方案。

    function namedForkJoin(map: {[key: string]: Observable<any>}): Observable<{[key: string]: any}> {
        // Get object keys
        const keys = Object.keys(map);
    
        // If our observable map is empty, we want to return an empty object
        if (keys.length === 0) {
            return of({});
        }
    
    
        // Create a fork join operation out of the available observables
        const forkJoin$ = Observable.forkJoin(...keys.map(key => map[key]))
    
        return forkJoin$
            .map(array => {
                const result = {};
                for (let index = 0; index < keys.length; index++) {
                    result[keys[index]] = array[index];
                }
    
            }));
    }
    

    1从输入地图中获取关键点。 2使用这些键获得一个可观察的数组,并将其传递给fork join。 三。添加一个映射函数,将生成的数组转换回对象。