RXJS等待其他可观察到的

时间:2019-02-05 14:41:41

标签: rxjs rxjs5

我需要订阅结果,但是要等到中间操作完成后才能得到结果。诀窍是我“访问”我的结果以填充它:

// a service that gets a model
service.getModel(): Observable<MyModel>;

// I need to enrich my model before consuming it
service.getModel()
    .makeSureAllCodesAreFetched(data => visitModel(model))
    .subscribe(data => console.log("data is ready: ", data));

// a visitor that visits the model tree and enriches the leaves
// recursively visit the branches
visitModel(model: MyModel) {
    if (model.isLeaf) {
       // on condition, call a service to fetch additional data
       service.fetchCodes(model.codeKey).subscribe(codes => model.codes = codes);
    } else {
        model.properties.forEach(prop: MyModel => visit(prop));
    }
}

我尝试使用merges和forkJoin()失败。我只想确保在预订数据之前完成对fetchCodes()的所有调用,无论结果如何。

1 个答案:

答案 0 :(得分:0)

我找到了解决方案,但是我认为这并不是最干净的方法。

// a service that gets a model
service.getModel(): Observable<MyModel>;

// I need to enrich my model before consuming it
service.getModel()
    .pipe(
        mergeMap(data => forkJoin(visitModel(model))))
    .subscribe(data => console.log("data is ready: ", data[0]));

// a visitor that visits the model tree and enriches the leaves
// recursively visit the branches
visitModel(model: MyModel, obs?: Observable<MyModel>[]): Observable<MyModel>[] {
    if (obs === undefined) {
        obs = [];
        obs.push(of(model)); // make sure the very first Observable is the root
    }
    if (model.isLeaf) {
       // on condition, call a service to fetch additional data
       // push Observable result in the array
       obs.push(service.fetchCodes(model.codeKey).map(codes => {
           model.codes = codes;
           return model;
       }));
    } else {
        model.properties.forEach(prop: MyModel => visit(prop, obs)); // recursive call
    }
    return obs;
}

我的访客实际上会将所有对fetchCodes()的呼叫追加到Observables的数组中并返回。这样forkJoin将等待所有呼叫完成。技巧(也是肮脏的部分)是,我必须确保第一个Observable实际上是我感兴趣的根元素。