在我的Angular 2应用程序中,我需要发出一系列的http请求。我有两个服务,A和B,每个服务都发出请求,A.get()和B.get(),它们从API获取数据并将它们存储在它们的服务中。这两个函数可以同时调用,但是我还有第三个请求doSomething(),它依赖于A.get()和B.get()的结果。由于A.get()和B.get()都将其响应存储在本地,因此它们的返回值最终是RxJs订阅。如下所示:
class A{
public data;
public get(){
return api.call(params).subscribe((response)=>{ this.data = response.json();})
}
}
class B{
public data;
public get(){
return api.call(params).subscribe((response)=>{ this.data = response.json();})
}
}我的组件看起来像这样:
class MyComponent{
constructor(private a: A, private b: B){
a.get();
b.get();
this.doSomething(a.data, b.data);
}
doSomething(aData, bData){
...
}
}我的问题是doSomething()失败了,因为a.get()和b.get()已经完成了http请求。我需要一种方法来保持呼叫doSomething(),直到我的其他呼叫完成。我已经找遍了所有的地方,但在这个问题上没有任何运气。RxJs文档给出了几种合并Observables的方法,但在本例中我没有这些方法。
发布于 2017-02-09 12:22:45
好的,你想要的东西可以通过这个来实现:
class A {
private data;
public get(): Observable<any> {
// this is a very primitive caching just to show concept
if (this.data) {
return Observable.of(this.data);
}
// In real life it would be something like this:
// let call = this.http.get(...).map(r => r.json())
let call = Observable.of("some value A");
return call.do(s => this.data = s);
}
}
class B {
private data;
public get(): Observable<any> {
if (this.data) {
return Observable.of(this.data);
}
let call = Observable.of("some value B");
return call.do(s => this.data = s);
}
}
class MyComponent {
constructor(private a: A, private b: B) {
Observable
.zip(this.a.get(), this.b.get(), (a: any, b: any) => { return { a: a, b: b } })
.subscribe((r) => {
this.doSomething(r.a, r.b);
});
}
doSomething(aData, bData) {
console.log("aData", aData);
console.log("bData", bData);
}
}这是对您的代码的修改。正如您所看到的,不需要订阅服务组件中的可观察对象。甚至不需要在服务组件之外单独订阅它们。我们只需以某种方式组合可观测对象,就可以在单个最终的订阅()中直接获得最终结果。
更新
do()和subscribe()有什么区别。
稍微简化一下(跳过热门的可观察对象),直到您订阅了可观察管道,它才会开始执行任何操作。do()只是众多运算符中的一个,这些运算符被设计为在可观察对象链中产生一些“副作用”,例如,它可以在可观察管道的中间输出一些中间结果,以供调试之用。这是主要的区别。因此,您可以在没有do()的情况下在subscribe()中获得某些内容,但是如果没有subscribe(),则在do()中不会获得任何内容。
发布于 2018-02-13 13:35:54
通过将订阅移动到组件,使用Observable.forkJoin可以轻松解决您的问题。它需要一个冷可观察数组,在订阅之后,您将收到一个结果数组。如下所示:
Observable.forkJoin([
a.get(),
b.get()
]).subscribe(
results => {
doSomething(results[0], results[1]);
},
err => {
//handle error
}
);直到两个请求都进入,订阅中的回调才会被调用。
如果a.get()或b.get()失败,将调用error方法
https://stackoverflow.com/questions/42126153
复制相似问题