从两个依赖项组成 Observable
Compose Observable from two dependant
我需要从另外两个 Observable 的值组成一个 Observable。答案是 zip 运算符。但我的情况更复杂。
我有一个 id 的 A.
A {id, name, idOfRelatedB} //first observable
B {...} // second
因此,为了获取 B,我需要先获取 A 以检索 B 的 ID。最后我需要 return 一个包含 A 和 B 的 Observable。
如何在 RX 中处理。
我在angular/typescript中不成功的解决方案:
@Injectable()
export class StrategyResolver implements Resolve<StrategyWithSourceCode> {
constructor(private strategyService: StrategyService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> {
const strategyId = route.paramMap.get('strategyId');
let sourceCodeObs: Observable<SourceCode>;
let strategy: Strategy;
this.strategyService.getStrategy(parseInt(strategyId)).subscribe(value => {
strategy = value;
sourceCodeObs = this.strategyService.getStrategySource(parseInt(strategyId), strategy.sourceCodeId);
});
return zip(of(strategy), sourceCodeObs, (v1: Strategy, v2: SourceCode) => ({v1, v2}));
}
}
更新:在用户 madjaoue(感谢他)的帮助下使用 rxjs 6 的任何特定的正确解决方案。
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> {
const strategyId = route.paramMap.get('strategyId');
return this.strategyService.getStrategy(parseInt(strategyId)).pipe(
concatMap(strategy => {
let sourceCodeObs = this.strategyService.getStrategySource(parseInt(strategyId), strategy.sourceCodeId);
return zip(of(strategy), sourceCodeObs, (v1: Strategy, v2: SourceCode) => ({v1, v2}));
})
)
}
您离答案并不遥远。这是对您的代码的轻微修改,可以满足您的需求。
const strategyObs = this.strategyService.getStrategy(parseInt(strategyId));
// use concatMap to combine two streams
strategyObs.concatMap(strategy => {
let sourceCodeObs = this.strategyService.getStrategySource(parseInt(strategyId), strategy.sourceCodeId);
// zip the response of the first service with the second
return zip(Observable.of(strategy), sourceCodeObs)
});
.subscribe( ([A, B]) => ...)
请注意,您可以将 concatMap
替换为其他运算符,例如 switchMap
、 mergeMap
或 exhaustMap
。所有人都会合并您的流,但方式不同。请检查 concatMap
是否适合您的情况。
我需要从另外两个 Observable 的值组成一个 Observable。答案是 zip 运算符。但我的情况更复杂。 我有一个 id 的 A.
A {id, name, idOfRelatedB} //first observable
B {...} // second
因此,为了获取 B,我需要先获取 A 以检索 B 的 ID。最后我需要 return 一个包含 A 和 B 的 Observable。 如何在 RX 中处理。
我在angular/typescript中不成功的解决方案:
@Injectable()
export class StrategyResolver implements Resolve<StrategyWithSourceCode> {
constructor(private strategyService: StrategyService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> {
const strategyId = route.paramMap.get('strategyId');
let sourceCodeObs: Observable<SourceCode>;
let strategy: Strategy;
this.strategyService.getStrategy(parseInt(strategyId)).subscribe(value => {
strategy = value;
sourceCodeObs = this.strategyService.getStrategySource(parseInt(strategyId), strategy.sourceCodeId);
});
return zip(of(strategy), sourceCodeObs, (v1: Strategy, v2: SourceCode) => ({v1, v2}));
}
}
更新:在用户 madjaoue(感谢他)的帮助下使用 rxjs 6 的任何特定的正确解决方案。
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> {
const strategyId = route.paramMap.get('strategyId');
return this.strategyService.getStrategy(parseInt(strategyId)).pipe(
concatMap(strategy => {
let sourceCodeObs = this.strategyService.getStrategySource(parseInt(strategyId), strategy.sourceCodeId);
return zip(of(strategy), sourceCodeObs, (v1: Strategy, v2: SourceCode) => ({v1, v2}));
})
)
}
您离答案并不遥远。这是对您的代码的轻微修改,可以满足您的需求。
const strategyObs = this.strategyService.getStrategy(parseInt(strategyId));
// use concatMap to combine two streams
strategyObs.concatMap(strategy => {
let sourceCodeObs = this.strategyService.getStrategySource(parseInt(strategyId), strategy.sourceCodeId);
// zip the response of the first service with the second
return zip(Observable.of(strategy), sourceCodeObs)
});
.subscribe( ([A, B]) => ...)
请注意,您可以将 concatMap
替换为其他运算符,例如 switchMap
、 mergeMap
或 exhaustMap
。所有人都会合并您的流,但方式不同。请检查 concatMap
是否适合您的情况。