Ну, у вас есть несколько вопросов / проблем здесь. Начну с самого простого. Как вы получаете наблюдаемое от функции / объекта? Ответ через наблюдаемый из :
return of(data);
Но вы избежали более масштабной проблемы, а именно: как отложить возврат данных до тех пор, пока наблюдаемые дочерние объекты не передадут свои значения? Вы ищете forkJoin . Через документы:
forkJoin
будет ожидать завершения всех переданных наблюдаемых, а затем будет выдавать массив с последними значениями из соответствующих наблюдаемых. Поэтому, если вы передадите n
Observables оператору, результирующий массив будет иметь значения n
, где first value - это последнее, что испускается первым Observable, второе значение - это последнее, что испускается вторым Observable, и так далее. Это означает, что forkJoin
не будет излучать более одного раза и завершится после этого.
У вас также есть несколько других проблем. Например, вы никогда не подписываетесь на this.getClientData()
или this.otherData()
. Наблюдаемые объекты лениво исполняются. Код в вашей наблюдаемой не будет выполняться, пока что-то не подпишется на него. От документов :
Код внутри Observable.create(function subscribe(observer) {...})
представляет «Наблюдаемое выполнение», ленивое вычисление, которое происходит только для каждого Наблюдателя, который подписывается .
Это также выглядит так, как будто вы используете pipe/map
в попытке установить свойство для вашего data
объекта. Но вы никогда не устанавливаете data.client
или data.other
, поэтому они всегда будут пустыми.
Итак, собрав все воедино, вы увидите, как может выглядеть ваш код с симулированной задержкой сервера, чтобы показать, что forkJoin
ожидает завершения обеих наблюдаемых:
import { Injectable } from '@angular/core';
import { Observable, of, forkJoin } from 'rxjs';
import { delay } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class TestService {
getData(): Observable<ServerResponse> {
const allOperations = forkJoin(
this.getClientData(),
this.getOtherData()
);
const observable = Observable.create(function subscribe(observer) {
// Wait until all operations have completed
allOperations.subscribe(([clientData, otherData]) => {
const data = new ServerResponse;
// Update your ServerReponse with client and other data
data.otherdata = otherData.other;
data.client = clientData.client;
// Now that data is 100% populated, emit to anything subscribed to getData().
observer.next(data);
observer.complete();
});
});
// We return the observable, with the code above to be executed only once it is subscribed to
return observable;
}
getClientData() : Observable<any> {
return of({ client: 'Client 1' });
}
getOtherData(): Observable<any> {
// Fake server latency
return of({ other: 'Other data that takes a while to return from server...' })
.pipe(delay(2000));
}
}
export class ServerResponse {
client: string;
otherdata: string;
}
Если вы позвоните по номеру getData()
и подпишитесь на наблюдаемую , вы увидите, что forkJoin
работает, как предполагалось, и нам нужно подождать 2 секунды, пока обе дочерние наблюдаемые завершатся, а наша наблюдаемая излучит значение:
this.testService.getData().subscribe(data => {
console.log(data);
});
Похоже, вы новичок в RxJS / асинхронном программировании. Я предлагаю прочитать отличное введение в RxJs, когда у вас есть шанс. Сначала это может быть сложно, но с практикой это станет второй натурой.