Как можно совместить несколько действий с наблюдаемыми? - PullRequest
0 голосов
/ 03 мая 2018

Я работаю над проектом Angular 4, и я новичок с Observable .

Моя цель - выполнить одну функцию после результата трех HTTP-запросов и обогатить мои модели результатами HTTP-запроса.

Я решил свою проблему с помощью наблюдаемого, как следующий код, но я думаю, что это не правильный путь:

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

[EDIT]

Я пробовал решение Оскара. Проблема заключается в том, что обратный вызов подписки не выполняется, но если я добавлю одну Observer.completed () в одну функцию, выполняется «завершенный обратный вызов», но я не могу получить доступ к данным.

Я воспроизвел там мой случай https://jsfiddle.net/2n6b0ug3/

Большое спасибо

1 Ответ

0 голосов
/ 03 мая 2018

Да, с оператором 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 также может получить массив наблюдаемых, если вы хотите, чтобы число запросов было динамическим, и результирующая наблюдаемая завершится, когда завершатся все другие наблюдаемые. Конечно, если один из наблюдаемых выдает ошибку, вы получите ошибку (первую). В этом случае результат других наблюдаемых будет игнорироваться.

Подробнее: https://www.learnrxjs.io/operators/combination/forkjoin.html

Это, примерно, эквивалент Promise.all

EDIT

Я разбудил ваше jsfiddle, чтобы исправить ваш пример: https://jsfiddle.net/hmv20xjh/1/. Проблема в вашем коде состоит в том, что ваши наблюдаемые никогда не завершаются, а forkJoin возвращает последнее значение наблюдаемой и делает это только после завершения. Итак, в вашем коде наблюдаемое, которое возвращает forkJoin, просто ждет вечно и никогда не возвращает значения.

В моём, однако, наблюдаемые завершены. forkJoin - хороший оператор для ожидания наблюдаемых объектов, представляющих HTTP-запрос, поскольку они дают только один результат и затем завершаются. Если вам нужно объединить наблюдаемые, которые дают несколько результатов, не дожидаясь их завершения, вам нужно использовать более сложные операторы, такие как flatMap или mergeMap

...