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

ilM*_*ion 3 observable rxjs typescript angular

我正在处理一个 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);
    });
}
Run Code Online (Sandbox Code Playgroud)

RxJS 是否允许组合多个操作,如以下伪代码?

function loadData(callback: Function): void {

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

}
Run Code Online (Sandbox Code Playgroud)

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

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

[编辑]

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

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

非常感谢

Osc*_*Paz 5

是的,与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 => {

);
Run Code Online (Sandbox Code Playgroud)

其实forkJoin也可以接收一个observable数组,如果你想让请求的数量是动态的,那么生成的observable会在所有其他observable完成时完成。当然,如果其中一个 observable 抛出错误,你会得到一个错误(第一个)。在这种情况下,其他 observables 的结果将被忽略。

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

大致相当于 Promise.all

编辑

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

但是,在我的情况下,可观察对象确实完成了。forkJoin是等待表示 HTTP 请求的 observables 的好操作符,因为它们只产生一个结果然后完成。如果您需要观测合并能产生多种结果,而无需等待他们去完成,你需要使用更多的复杂的运营商如flatMapmergeMap