通过使用Http,我们调用一个执行网络调用并返回http observable的方法:
getCustomer() {
return this.http.get('/someUrl').map(res => res.json());
}
Run Code Online (Sandbox Code Playgroud)
如果我们采用这个可观察的并添加多个订阅者:
let network$ = getCustomer();
let subscriber1 = network$.subscribe(...);
let subscriber2 = network$.subscribe(...);
Run Code Online (Sandbox Code Playgroud)
我们想要做的是确保这不会导致多个网络请求.
这可能看起来像是一个不寻常的场景,但实际上很常见:例如,如果调用者订阅了observable以显示错误消息,并使用异步管道将其传递给模板,那么我们已经有两个订阅者.
在RxJs 5中这样做的正确方法是什么?
也就是说,这似乎工作正常:
getCustomer() {
return this.http.get('/someUrl').map(res => res.json()).share();
}
Run Code Online (Sandbox Code Playgroud)
但这是在RxJs 5中这样做的惯用方式,还是我们应该做其他事情呢?
注意:根据Angular 5 new HttpClient,.map(res => res.json())所有示例中的部分现在都没用,因为现在默认采用JSON结果.
我有两个需要通过服务共享数据的Angular2组件:
@Injectable()
export class SearchService {
private searchResultSource = new Subject<string>()
searchResult$ = this.searchResultSource.asObservable()
setSearchResults(_searchResult: string): void {
this.searchResultSource.next(_searchResult)
}
}
Run Code Online (Sandbox Code Playgroud)
假设ComponentA已呈现并且它通过发出事件SearchService.setSearchResults.然后用户导航到ComponentB,也订阅searchResult$.但是,ComponentB永远不会观察发出的事件,ComponentA因为它searchResult$在ComponentA发出事件时没有订阅,因为它不存在.
如何创建Observable向每个新订阅者发送最后一个事件的内容?
我发现了许多缓存反应式可观察量的方法,更具体地说,是http请求的结果.但是,由于以下原因,我对提议的解决方案并不完全满意:
1.此答案/sf/answers/2549206831/使用私有字段存储第一个请求的结果,并在所有后续调用中重用它.
代码:
private data: Data;
getData() {
if(this.data) {
return Observable.of(this.data);
} else {
...
}
}
Run Code Online (Sandbox Code Playgroud)
可悲的是,可观察力的力量完全被忽略了 - 你手动完成所有的东西.事实上,如果我对将结果分配给局部变量/字段感到满意,我就不会寻找合适的解决方案.我认为一个不好的做法的另一个重要的事情是服务不应该有一个状态 - 即应该没有包含从一个调用到另一个调用的数据的私有字段.清除缓存相当容易- 只需将this.data设置为null,即可重新执行请求.
2.这个答案/sf/answers/2548910241/建议使用ReplaySubject:
private dataObs$ = new ReplaySubject(1);
constructor(private http: Http) { }
getData(forceRefresh?: boolean) {
// If the Subject was NOT subscribed before OR if forceRefresh is requested
if (!this.dataObs$.observers.length || forceRefresh) {
this.http.get('http://jsonplaceholder.typicode.com/posts/2').subscribe(
data => this.dataObs$.next(data),
error => {
this.dataObs$.error(error);
// Recreate the Observable as after Error we …Run Code Online (Sandbox Code Playgroud) 使用Angular 2,我从服务接收JSON数据.像这样的东西:
{
"customerName": "foo",
"customerAddress": "123 Somewhere",
"products":
[
{
"productName": "bar",
"productNumber": 123
},
{
"productName": "baz",
"productNumber": 456
}
]
}
Run Code Online (Sandbox Code Playgroud)
在我的组件中,我订阅了服务以获取填充customerData.
private _getData() {
this._myService
.getData()
.subscribe(
customerData => this.customerData = customerData,
error => this.errorMessage = error
);
}
Run Code Online (Sandbox Code Playgroud)
此代码正常工作.
在JSON转储中,有两个数据"分组",即客户数据和产品数据,后者在数组中.理想情况下,我想分别填充产品数据.像这样的东西:
.subscribe(
customerData => this.customerData = customerData,
productData => this.productData = customerData.products
error => this.errorMessage = error
);
Run Code Online (Sandbox Code Playgroud)
这是可能的,如果是这样,我将如何编码订阅?