RXJS ждать других наблюдаемых - PullRequest
0 голосов
/ 05 февраля 2019

Мне нужно подписаться на результат, но дождаться завершения промежуточных операций, прежде чем получить результат.Хитрость в том, что я «посещаю» свой результат, чтобы заполнить его:

// 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));
    }
}

Я попытался поиграть с слияниями и forkJoin () безуспешно.Я просто хочу убедиться, что все вызовы fetchCodes(), независимо от результата, выполняются до того, как мои данные будут подписаны.

1 Ответ

0 голосов
/ 05 февраля 2019

Я нашел решение, но оно не самое чистое, на мой взгляд.

// 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 на самом деле является корневым элементом, который меня интересует.

...