javascript - 做(点击)与订阅

标签 javascript angular rxjs

编辑:在 RxJs 6 之前,tap 被称为 do 。更新标题以反射(reflect)水龙头。

我想了解使用 Observables 的 .subscribe.do 方法的最佳实践是什么。

例如,如果我需要在从服务器加载初始数据后做一些工作

const init$: Observable<MyData> = this._dataService.getData();

init$
  .do((initialData: MyData) => {
    this.data = initialData; // at this step I am initializing the view
  })
  .switchMap(() => loadExtraData)
  .subscribe((extraData) => {
     doSomething(extraData, this._data); // I need this._data here
  }); 

我可以用 .subscribe 做同样的事情

const init$: Observable<MyData> = this._dataService.getData()
  .shareReplay(1);

init$
  .subscribe((initialData: MyData) => {
    this.data = initialData; // at this step I am initializing the view
  })

init$
  .combineLatest(loadExtraData)
  .subscribe(([initialData, extraData]) => {
     doSomething(extraData, initialData); // I need this._data here
  }); 

哪个更好,为什么?

最佳答案

编辑:对于 RxJS 6 或更高版本,将 do 读作 tap

do is used for side-effects. subscribe is used to invoke an observable. Replacing do with subscribe creates undesired results. Replacing subscribe with do will not even invoke the stream.

考虑这些例子:

使用订阅:

const testObservable = Rx.Observable.create(function(observer){
   console.log('some heavy task, may be network call ');
   observer.next('success');
});

testObservable.subscribe(function(res){
    console.log('action 1');
});

testObservable.subscribe(function(res){
   console.log('action 2');
});

上面代码的输出是

"some heavy task, may be network call "
"action 1"
"some heavy task, may be network call "
"action 2"

您可以看到 Rx.Observable.create 被执行了两次。我们的目标是只执行一次,但与操作 2 一起执行操作 1

使用:

const testObservable = Rx.Observable.create(function(observer){
   console.log('some heavy task, may be network call ');
   observer.next('success');
});

testObservable
    .do(function(res){
        console.log('action 1');
    })  
    .subscribe(function(res){
        console.log('action 2');
    });

输出为

"some heavy task, may be network call "
"action 1"
"action 2"

这才是我们真正想要的。我们需要“ Action 2”,但在此之前还要执行“ Action 1”。

为什么叫副作用:

因为它不会像其他操作符那样影响stream的流动。它接受响应,做一些事情,即使它修改了响应,流也会忽略它。例如:

testObservable
    .do(function(res){
        console.log('action 1');
        return res+'some other text';
    })  
    .subscribe(function(res){
        console.log('action 1');
    });

上面的代码仍然会给出与以前相同的输出。因此,无论您在 do 中执行什么,流都将忽略它并继续执行。

If we are doing pure 'functional reactive programming' we don't want any side effects in the stream. So, do is discouraged and mostly used only for debugging purposes .

关于javascript - 做(点击)与订阅,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45321516/

相关文章:

javascript - Angular 2 - 升级到 rc4 会引发脚本错误

angular - GitHub Pages 加载资源失败

css - 如何摆脱 Angular Material 芯片上 100% 的水平宽度?

下一个可观察后的 Angular 回调

javascript - Chrome/V8如何处理javascript中的大对象?

javascript - 通过单击 div 启用/禁用所有音效 - javascript

javascript - 如何根据正则表达式匹配将字符串路由到函数?

javascript - 如何将可观察数据通过管道传输到可观察数组中?

javascript - 不通过调度程序的 RxJS 测试 Observable 序列

javascript - 在 Nativescript 中从本地 PC 加载 JSON 文件