使用一个 observable 的输出作为另一个 angular 的输入的正确方法是什么?

Dus*_*one 0 asynchronous observable rxjs angular

我需要使用异步 (http) 返回调用服务,并将其输出用作服务方法(返回可观察对象)的附加输入。在 Angular 4+ 中执行此操作的最佳方法是什么?

我已经尝试在第一个服务的“订阅”方法中“链接”结果,但这样做我的服务总是返回“空”。

public secondServiceCall: Observable<object> {
   this.firstService.next().subscribe(result=> {
      item.number = result;

      return this.httpService.post<object>('/new', item);
   });
}
Run Code Online (Sandbox Code Playgroud)

我预计该函数在 firstService 的订阅完成之前不会返回(类似异步),但这并没有发生 - 相反,我在调用函数中得到了 'null'。

我还尝试将 firstService 调用用作 observable - 这将正确返回第二个 observable,但在触发第二个 observable 之前从不等待“then”函数执行。

this.firstService.next().toPromise().then(result=> {
  item.number = result;
});

return return this.httpService.post<object>('/new', item);
Run Code Online (Sandbox Code Playgroud)

Phi*_*hix 5

导入 switchMap 操作符:

import { switchMap } from 'rxjs/operators';
Run Code Online (Sandbox Code Playgroud)

无论其中的方法firstService返回任何item内容的 observable,都将其包装如下:

public secondServiceCall: Observable<object> {
   return this.firstService.someMethod().pipe(
      switchMap(item => {
         return this.httpService.post<object>('/new', item);
      })
   ) // result of your HTTP call based on item from firstService is now available when you subscribe
}
Run Code Online (Sandbox Code Playgroud)

它的作用是执行firstService返回 an 的任何方法Observable<item>,然后切换httpService.post调用,该调用将firstService方法的结果作为第一个参数提供。

编辑:感谢 JB Nizet,结合了答案的多次迭代:/


Yev*_*iuk 5

在您的情况下,使用哪个组合运算符并不重要:flatMap,concatMapswitchMap; 它们的行为相同,因为Angular'shttp仅发出一次值并立即完成。

通常你会更喜欢concatMap更多,因为这个运算符尊重发射的顺序(这意味着如果你的 Observables 中有一些延迟的调用,它们将被一个接一个地执行,而 和flatMap可能switchMap会导致不确定的结果,更多详细信息请参见https:// www.baeldung.com/rxjava-flatmap-switchmap)。


太长了;使用concatMap

this.http.get('one').pipe(
  concatMap(result => this.http.get('two'))
)
Run Code Online (Sandbox Code Playgroud)