编辑:在 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. Replacingdo
withsubscribe
creates undesired results. Replacingsubscribe
withdo
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/