返回可观察的两个函数;需要根据另一个的结果有条件地调用一个

时间:2018-01-13 01:44:13

标签: typescript rxjs observable reactive-programming

我是TypeScript和反应式编程(RxJS库,特别是)的完全新手,我认为我从根本上缺少一些东西,因为我无法弄清楚如何实现我的用例。

我的用例的上下文如下。我有用我继承的TypeScript编写的代码。代码包括两个函数:foo1和foo2。这两个函数执行一些相对较长的操作并返回“Observable”类型的对象。我无法修改这两个功能。我需要编写一个返回Observable的新函数,并执行以下操作:

  • 调用函数foo1。
  • 如果foo1成功,则调用函数foo2并返回该函数返回的内容。
  • 如果foo1失败,则返回一个解析为错误的Observable。

有可能吗?

4 个答案:

答案 0 :(得分:2)

假设您有first(): Observable<{succeed: boolean, error: error, value: any}>second(): Observable<...>

first.pipe(
  mergeMap((ret) => 
     ret.succeed ? second(ret.value) : Observable.throw(ret.error)
   )
)

答案 1 :(得分:1)

return foo1()。mergeMap(foo1Result =&gt; foo2());

答案 2 :(得分:0)

如果第一个发出错误而第二个不会执行,则需要链接两个调用。请参阅以下示例

  callDataService1(){
    this.dataService.getData1()
      .subscribe(data =>
      { this.myData = data, this.callDataService2()},
        error => this.errorMessage = error);
    }
    callDataService2(){
     this.dataService.getData2()`
      .subscribe(data =>
      { this.myData2 = data},
        error => this.errorMessage = error);
    }

希望它有所帮助。当我需要来自通话的数据来制作另一个

时,我确实喜欢这样

答案 3 :(得分:0)

你可以使用switchMap来调用你的第一个observable然后切换到第二个(取消第一个)。如果您的第一个可观察foo1错误,则不会调用第二个错误。在subscribe方法中,第二个参数采用错误回调。

注意:switchMap的第二个参数采用选择器函数,它允许您组合发出的外部可观察值和内部值:f1, f2) => ({ f1, f2 }) 这是一个例子:

此外,如果要求foo1不断发出,请在示例中将switchMap替换为flatMap

    const foo1 = () => {
        return Rx.Observable.of({ id: 'foo1' }); 
    }

    const foo2 = () => {
        console.log('calling foo2');
        return Rx.Observable.of({ id: 'foo2' }); 
    }

    foo1()
        .switchMap((f1) => foo2(), (f1, f2) => ({ f1, f2 }))
        .subscribe(combined => console.log(combined), err =>console.error(err) );
<script src="https://unpkg.com/@reactivex/rxjs@5.5.6/dist/global/Rx.js"></script>

以下是foo1错误的示例,您会注意到foo2未被调用。:

const foo1 = () => {
    return Rx.Observable.throw('bad foo!')
}

const foo2 = () => {
    console.log('calling foo2');
    return Rx.Observable.of({ id: 'foo2' }); 
}

foo1()
    .switchMap((f1) => foo2(), (f1, f2) => ({ f1, f2 }))
    .subscribe(combined => console.log(combined), err =>console.error('>>err',err) );
<script src="https://unpkg.com/@reactivex/rxjs@5.5.6/dist/global/Rx.js"></script>