在没有回调参数的情况下调用订阅时,RXJS do 运算符不会在流中被命中
RXJS do operator not getting hit in stream when subscribe is called without a callback parameter
我正在尝试使用类似 Redux 的模式来维护服务中特定功能的状态。我的意图是消费者可以通过调用 getItem1()
或 getItem2()
来订阅单独的数据流,然后根据需要在服务上调用操作方法,例如 initializeItem1()
或 initializeItem2()
调度将改变商店状态的动作。在服务中,可以从 http 调用或提供的 plnkr 中模拟的其他方式获取数据。
https://plnkr.co/edit/f3HLp5C8ckIpjNsM8dTm?p=preview
具体来说,我不明白的是,为什么在我的示例代码中,除非我将 this.service.initializeItem1().subscribe();
更改为 this.service.initializeItem1().subscribe(() => {});
,否则 getItem1()
返回的 observable 不会发出值。有人可以解释一下这是否看起来像是 rxjs 中的一个错误,是否有一个很好的/已知的解释来说明为什么会这样,或者我是否只是遗漏了什么?我感谢社区可以提供给我的任何见解。谢谢。
组件
//our root app component
import {Component, OnInit} from '@angular/core'
import {Observable} from 'rxjs/Rx'
import {SampleService} from './sample.service'
@Component({
selector: 'my-app',
template: `
<div>
<h2>Item 1 Value</h2>
<div>{{ item1 }}</div>
<h2>Item 2 Value</h2>
<div>{{ item2 }}</div>
</div>
`,
})
export class App implements OnInit {
name:string;
item1: string;
item2: string;
constructor(private service: SampleService) { }
ngOnInit() {
this.item1 = this.service.getItem1().subscribe(item1 => this.item1 = item1);
this.item2 = this.service.getItem2().subscribe(item2 => this.item2 = item2);
/* broken */
//Item 1 does not display
//Item 2 displays as expected
this.scenario1();
/* works */
//Item 1 displays as expected
//Item 2 displays as expected
// this.scenario2();
}
private scenario1() {
this.service.initializeItem1().subscribe();
this.service.initializeItem2().subscribe();
}
private scenario2() {
this.service.initializeItem1().subscribe(() => {});
this.service.initializeItem2().subscribe();
}
}
服务
import {Injectable} from '@angular/core'
import {Observable, Subject} from 'rxjs/Rx'
import { Http, Headers } from '@angular/http';
@Injectable()
export class SampleService {
constructor(private http: Http) { }
private headers: Headers = new Headers({ 'Content-Type': 'application/json' });
private _store: Subject<any> = new Subject<any>();
private store = this._store.asObservable()
.startWith({})
.scan(reducer);
public initializeItem1(): Observable<string> {
return this.http.get('api/foobar')
.map(response => response.json().item).do(data => {
console.log('not hit in scenario 1, but hit in scenario 2:', data);
this._store.next({
type: 'INITIALIZE_1',
payload: data
});
});
}
public initializeItem2(): Observable<string> {
return Observable.of('foobar-2').do(data => {
console.log('hit in scenario 1 and scenario 2:', data);
this._store.next({
type: 'INITIALIZE_2',
payload: data
});
});
}
getItem1(): Observable<string> {
return this.store.map(store => store.settings1);
}
getItem2(): Observable<string> {
return this.store.map(store => store.settings2);
}
}
function reducer(store, action) {
switch(action.type) {
case 'INITIALIZE_1':
return Object.assign({ }, store, {
initialSettings: action.payload,
settings1: action.payload
});
case 'INITIALIZE_2':
return Object.assign({ }, store, { settings2:action.payload });
default:
return store;
}
}
这是 RxJS 5 到 RxJS 5.2.0 版本中的错误。已经修复了,但是还没有发布。
唯一的解决方法是使用任何订阅者,例如 () => {}
(我认为只使用 {}
也应该有效)。
在 RxJS 上合并 PR GitHub 修复了这个问题:
相关问题:
我正在尝试使用类似 Redux 的模式来维护服务中特定功能的状态。我的意图是消费者可以通过调用 getItem1()
或 getItem2()
来订阅单独的数据流,然后根据需要在服务上调用操作方法,例如 initializeItem1()
或 initializeItem2()
调度将改变商店状态的动作。在服务中,可以从 http 调用或提供的 plnkr 中模拟的其他方式获取数据。
https://plnkr.co/edit/f3HLp5C8ckIpjNsM8dTm?p=preview
具体来说,我不明白的是,为什么在我的示例代码中,除非我将 this.service.initializeItem1().subscribe();
更改为 this.service.initializeItem1().subscribe(() => {});
,否则 getItem1()
返回的 observable 不会发出值。有人可以解释一下这是否看起来像是 rxjs 中的一个错误,是否有一个很好的/已知的解释来说明为什么会这样,或者我是否只是遗漏了什么?我感谢社区可以提供给我的任何见解。谢谢。
组件
//our root app component
import {Component, OnInit} from '@angular/core'
import {Observable} from 'rxjs/Rx'
import {SampleService} from './sample.service'
@Component({
selector: 'my-app',
template: `
<div>
<h2>Item 1 Value</h2>
<div>{{ item1 }}</div>
<h2>Item 2 Value</h2>
<div>{{ item2 }}</div>
</div>
`,
})
export class App implements OnInit {
name:string;
item1: string;
item2: string;
constructor(private service: SampleService) { }
ngOnInit() {
this.item1 = this.service.getItem1().subscribe(item1 => this.item1 = item1);
this.item2 = this.service.getItem2().subscribe(item2 => this.item2 = item2);
/* broken */
//Item 1 does not display
//Item 2 displays as expected
this.scenario1();
/* works */
//Item 1 displays as expected
//Item 2 displays as expected
// this.scenario2();
}
private scenario1() {
this.service.initializeItem1().subscribe();
this.service.initializeItem2().subscribe();
}
private scenario2() {
this.service.initializeItem1().subscribe(() => {});
this.service.initializeItem2().subscribe();
}
}
服务
import {Injectable} from '@angular/core'
import {Observable, Subject} from 'rxjs/Rx'
import { Http, Headers } from '@angular/http';
@Injectable()
export class SampleService {
constructor(private http: Http) { }
private headers: Headers = new Headers({ 'Content-Type': 'application/json' });
private _store: Subject<any> = new Subject<any>();
private store = this._store.asObservable()
.startWith({})
.scan(reducer);
public initializeItem1(): Observable<string> {
return this.http.get('api/foobar')
.map(response => response.json().item).do(data => {
console.log('not hit in scenario 1, but hit in scenario 2:', data);
this._store.next({
type: 'INITIALIZE_1',
payload: data
});
});
}
public initializeItem2(): Observable<string> {
return Observable.of('foobar-2').do(data => {
console.log('hit in scenario 1 and scenario 2:', data);
this._store.next({
type: 'INITIALIZE_2',
payload: data
});
});
}
getItem1(): Observable<string> {
return this.store.map(store => store.settings1);
}
getItem2(): Observable<string> {
return this.store.map(store => store.settings2);
}
}
function reducer(store, action) {
switch(action.type) {
case 'INITIALIZE_1':
return Object.assign({ }, store, {
initialSettings: action.payload,
settings1: action.payload
});
case 'INITIALIZE_2':
return Object.assign({ }, store, { settings2:action.payload });
default:
return store;
}
}
这是 RxJS 5 到 RxJS 5.2.0 版本中的错误。已经修复了,但是还没有发布。
唯一的解决方法是使用任何订阅者,例如 () => {}
(我认为只使用 {}
也应该有效)。
在 RxJS 上合并 PR GitHub 修复了这个问题:
相关问题: