如何将多个动作与observable结合起来?

时间:2018-05-03 15:22:26

标签: angular typescript rxjs observable

我正在开发一个Angular 4项目,我是Observable的新手。

我的目标是在三个HTTP请求的结果之后执行一个函数,并使用HTTP请求结果丰富我的模型。

我用observable解决了我的问题,如下面的代码,但我认为这不是正确的方法:

function loadData(callback: Function): void {
    this.httpRequestUno().subscribe(next => {
        this.httpRequestDue().subscribe(next => {
          this.httpRequestTre().subscribe(next => {
            callback();
          }, error => {
            console.log(error);
          });
        }, error => {
          console.error(error);
        });
      }, error => {
        console.error(error);
      });
}

function httpRequestUno():Observable<any>{
    let self = this;
    return new Observable<any>((observer) => {
        // my http request and...
        self.attributo1 = httpResult;
        observer.next(1);
    });
}

function httpRequestDue():Observable<any>{
    let self = this;    
    return new Observable<any>((observer) => {
        // my http request and...
        self.attributo2 = httpResult;
        observer.next(2);
    });
}

function httpRequestTre():Observable<any>{
    let self = this;    
    return new Observable<any>((observer) => {
        // my http request and...
        self.attributo3 = httpResult;
        observer.next(3);
    });
}

RxJS是否允许组合多个动作,如下面的伪代码?

function loadData(callback: Function): void {

    this.httpRequestUno().combine(this.httpRequestDue).combine(this.httpRequestTre).subscribe(result => {
        callback();
    });

}

有没有办法将所有结果传递给一个参数,如下面的伪代码?

this.httpRequestUno().combine(this.httpRequestDue).combine(this.httpRequestTre).subscribe(result => {
    let httpRequestUnoResult = result[0];
    let httpRequestDueResult = result[1];
    let httpRequestTreResult = result[2];
    callback();
});

[编辑]

我尝试过奥斯卡的解决方案。问题是订阅回调没有被执行但是如果我在一个函数中添加一个 observer.completed(),则执行“完成的回调”但我无法访问数据。

我在那里复制了我的案例https://jsfiddle.net/2n6b0ug3/

非常感谢

1 个答案:

答案 0 :(得分:2)

是的,forkJoin运营商:

const subscription = forkJoin(
    this.httpRequestUno(),
    this.httpRequestDue(),
    this.httpRequestTre()
).subscribe(value => {
     // value is an array with the results:
     [result-of-request-uno, results-of-rquest-due, result-of-request-tre]
}, error => {

);

实际上,forkJoin也可以接收一个observable数组,如果你想使请求数变为动态,并且当所有其他observable完成时,结果observable将完成。当然,如果其中一个observable抛出错误,你会收到一个错误(第一个错误)。在这种情况下,其他可观察量的结果将被忽略。

更多信息:https://www.learnrxjs.io/operators/combination/forkjoin.html

大致相当于Promise.all

修改

我分叉你的jsfiddle来修复你的例子:https://jsfiddle.net/hmv20xjh/1/。代码中的问题是你的observable永远不会完成,forkJoin返回一个observable的最后一个值,只有在完成时才会这样做。因此,在您的代码中,forkJoin返回的observable会一直等待,永远不会产生值。

然而,在我的观察中,观察者确实完成了。 forkJoin是一个很好的运算符,可以等待代表HTTP请求的observable,因为它们只生成一个结果然后完成。如果您需要合并产生多个结果的observable而不等待它们完成,则需要使用更复杂的运算符,例如flatMapmergeMap