#typescript #rxjs #observable
#typescript #rxjs #наблюдаемый
Вопрос:
Я пытаюсь использовать forkJoin
для получения результатов нескольких наблюдаемых (http-запросов в реальном коде) вместе.
К одному из исходных наблюдаемых ( mainObs
ниже) map
применен оператор, чтобы выходные данные имели тот же формат, что и другие наблюдаемые.
Моя проблема в том, что в forkJoin
subscribe первый результат является наблюдаемым, а не выводом первого наблюдаемого.
Вот пример кода с демонстрацией stackblitz.
Я что-то упустил?
import { forkJoin, Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
let mainObs = of("main").pipe(map(res => of({success: true, result: res})));
let listOfObservables: Observable<any>[] = [mainObs];
listOfObservables.push(createObs());
listOfObservables.push(createObs());
forkJoin(listOfObservables).subscribe((res: any[]) => {
console.log(res);
//Problem: res[0] is an Observable, not a value
console.log(res[0].success);// <==error
});
function createObs()
{
return of({success: true, result: "dummy"})
}
Комментарии:
1. Используйте subscribe на res[0].подписаться
Ответ №1:
of
создает новую наблюдаемую. Таким образом, вы mainObs
возвращаете новую наблюдаемую, когда она возвращается.
Вероятно, вы хотели вернуть фактический результат:
import { forkJoin, Observable, of } from "rxjs";
import { map } from "rxjs/operators";
let mainObs = of("main").pipe(map(res => ({ success: true, result: res })));
// creating a typed array helps preventing this problem early.
let listOfObservables: Observable<{ success: boolean; result: string }>[] = [
mainObs
];
listOfObservables.push(createObs());
listOfObservables.push(createObs());
forkJoin(listOfObservables).subscribe(
(res: { success: boolean; result: string }[]) => {
console.log(res);
console.log(res[0].success); // <== ok
}
);
function createObs() {
return of({ success: true, result: "dummy" });
}
Ответ №2:
1: map
of("main").pipe(
map(res => of({success: true, result: res}))
);
Это принимает строку «main», а затем сопоставляет эту строку с наблюдаемой. Это наблюдаемое излучается. То, что делает это наблюдаемое, здесь не имеет значения, поскольку на него никогда не подписывались.
2: mergeMap
of("main").pipe(
mergeMap(res => of({success: true, result: res}))
);
Это принимает строку «main», а затем сопоставляет эту строку с наблюдаемой. На возвращаемый наблюдаемый объект подписывается, и его выбросы передаются вперед. Наконец, {success: true, result: "main"}
выдается.
3: Вернуться к map
of("main").pipe(
map(res => ({success: true, result: res}))
);
Это принимает строку «main» и сопоставляет ее с объектом {success: true, result: "main"}
. Затем этот объект генерируется.
# 2 и # 3 имеют одинаковый конечный результат в этих примерах. Как и в большинстве задач, обычно существует несколько способов достижения одного и того же результата. # 3 является наиболее эффективным в этом случае, поскольку вы избегаете создания наблюдаемого и управления им с помощью mergeMap.