等待RxJs.Subscriptions完成后再继续 [英] Wait on RxJs.Subscriptions to finish before resuming

查看:189
本文介绍了等待RxJs.Subscriptions完成后再继续的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Angular 2应用中,我需要发出一系列http请求.我有两项服务,即A& B,每个发出请求A.get()B.get(),都从API获取数据并将其存储在其服务中.可以同时调用这两个,但是我有第三个请求doSomething(),这取决于A.get()B.get()的结果.由于A.get()B.get()都在本地存储其响应,因此它们的返回值最终是RxJs订阅.像这样:

In my Angular 2 app I need to make a series of http request. I have two services, A & B, that each make request, A.get() and B.get(), that gets data from the API and stores them in the their service. These two can be called at the same time, however I have a third request doSomething() that depends on the results of A.get() and B.get(). Since both A.get() and B.get() are storing their responses locally their return value ends up be the RxJs Subscription. Like so:

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();})
  }
}

我的组件看起来像这样:

My component looks something like this:

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的方法,但是在这种情况下,这不是我所拥有的.

My problem is doSomething() is failing because a.get() and b.get() have completed there http request yet. I need a way to hold of calling doSomething() until my other calls have completed. I've search all over but haven't had any luck with this issue. RxJs documentation gives a few ways you can merge Observables but that is not what I have in this case.

推荐答案

好吧,您可以通过以下方法实现:

Well, what you want can be achieved with this:

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);
    }
}

这是对您的代码的修改.如您所见,无需在服务组件内部订阅可观察对象.甚至不需要在服务组件之外单独订阅它们.只需以某种方式组合可观察对象,就可以直接在单个final subscription()中接收最终结果.

This is a modification of your code. As you see there's no need to subscribe to observables inside the service components. There's no even need to subscribe to them separately outside of service components. We can directly receive the ultimate result in the single final subscribe() just by combining observables in a certain way.

更新

do()和subscribe()有什么区别.

What is the difference between do() and subscribe().

简单一点(跳过热的可观察对象),可观察管道在您订阅它之前不会开始做任何事情. do()只是被设计为在可观察对象链中具有某些副作用"的许多运算符之一,例如,它可以在可观察管道的中间输出一些中间结果,以便控制台进行调试.这是主要区别.因此,您可以在中间没有do()的情况下在subscribe()中得到某些东西,但是没有subscribe()的情况下您将不会在do()中得到任何东西.

Simplifying a bit (skipping hot observables), observable pipe will not start to do anything until you subscribe to it. do() is just one of many operators designed to have some "side effects" in the chain of your observables, for example it can output some intermediate results in the middle of observable pipe to console for debugging purposes. This is the main difference. So, you can get something in subscribe() without do() in the middle, but you will not get anything in do() without subscribe().

这篇关于等待RxJs.Subscriptions完成后再继续的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆