RxJS-如何用可观察对象替换订阅中的回调

时间:2018-07-02 05:56:54

标签: angular rxjs

最近,我的一位同事在Angular 6应用程序的Subscription中实现了回调,如下所示:

callDoSomething() {
  this.doSomething(() => { 
    // logic from callback
   });
}

public doSomething(callback: any) {
  this.http.get('/api/doSomething').subscribe(data => {
    // do something with data
    if (callback) {
      callback();
    }
  }, error => {
    // do something with error
  });
}

我认为最好用RxJS Observable解决此“问题”。但是在实现/重构代码后,它似乎并不是更好的解决方案。该代码现在看起来更加复杂。是否有必要将管道投放到承诺中并以可观察的方式返回?

import { Observable, of as observableOf, from as observableFrom } from 'rxjs';
import { catchError, map } from 'rxjs/operators';

callDoSomething() {
    this.doSomething().subscribe((result) => {
    if (result) {
        // logic from callback
    }
    });
}

public doSomething() {
    let promise = this.http.get('/api/doSomething').pipe(
    map(data => {
        // do something with data
        return observableOf(true);
    }),
    catchError((error) => {
        // do something with error
        return observableOf(false);
    })
    ).toPromise()

    return observableFrom(promise);
}

是否有更好的方法来解决Observables的问题?还是我的同事有权使用简单的回调?

2 个答案:

答案 0 :(得分:1)

您无需强制转换为Promise,然后再次强制转换为Observable。还要看一下map函数。为什么从中返回truemap函数用于更改即将到来的数据,然后再传递已更改的数据。

public doSomething() {
    let observable= this.http.get('/api/doSomething').pipe(
    map(data => {
        // do something with data
        return observableOf(true);
    }),
    catchError((error) => {
        // do something with error
        return observableOf(false);
    }));

    return observable;
}

答案 1 :(得分:1)

恕我直言,回调是最简单的解决方案。完整的处理程序可能是一个更好的地方。如果您想使用可观察变量,那么我会坚持使用流语义。

如果您的目标是处理成功案例,但又不想从函数中获取数据,则可以返回一个空的,完整的可观察值。如果发生错误,您可以让它通过,也可以将其替换为以错误结尾的空的可观察对象。它类似于observable.of(true / false),但是依赖于流语义而不是任意值。

    doSomething() {
     return this.http.get('/api/doSomething').pipe(
        flatMap(data => {
          // do something with data
          return empty();
        }),
        catchError((error) => {
          // do something with error
          return throwError(error); //instead of error pass whatever you like
        })
      );
    }

    callDoSomething() {
      this.doSomething()
       .subscribe(
         undefined, //we don't handle data
         undefined, //we don't handle errors
         () => {// logic from callback}
       );
    }

如您所见,它的代码仍然比回调解决方案多得多。但是,如果有一天添加了错误回调,这可能是一个有趣的选择。可观察到的解决方案的好处是:没有。