我有一个类似的观察结果:
const original = Observable.of({
a: this.http.get('https://jsonplaceholder.typicode.com/todos/11'),
b: this.http.get('https://jsonplaceholder.typicode.com/todos/22'),
c: this.http.get('https://jsonplaceholder.typicode.com/todos/33')
});
我需要解析内部的可观察对象,并在订阅处理程序中获得如下内容:
{
a: ResponseFromServer,
b: ResponseFromServer,
c: ResponseFromServer,
}
我应该如何解决这个问题?
谢谢。
编辑:我已经弄清楚了,请阅读下文。
似乎很少有人知道* Map运算符曾经以resultSelector
作为第二个参数。现在在rxjs v6中,您可以使用inner map
做同样的事情,让我向您展示。
const original = Observable.of({
a: this.http.get('https://jsonplaceholder.typicode.com/todos/11'),
b: this.http.get('https://jsonplaceholder.typicode.com/todos/22'),
c: this.http.get('https://jsonplaceholder.typicode.com/todos/33')
});
const transformed = original.pipe(
mergeMap(sourceValue =>
forkJoin(_.values(sourceValue)).pipe(map(resolvedHttpRequests => {
// here you have access to sourceValue as well as resolvedHttpRequests so you can do manual join to match the data.
}))
)
)
答案 0 :(得分:2)
2020年更新
forkJoin(
// as of RxJS 6.5+ we can use a dictionary of sources
{
google: ajax.getJSON('https://api.github.com/users/google'),
microsoft: ajax.getJSON('https://api.github.com/users/microsoft'),
users: ajax.getJSON('https://api.github.com/users')
}
)
// { google: object, microsoft: object, users: array }
.subscribe(console.log);
https://www.learnrxjs.io/learn-rxjs/operators/combination/forkjoin
答案 1 :(得分:1)
他们在上面(用Observable.of
进行操作的方式实质上是创建较低可观察值的较高可观察值。
我认为一个更好的运算符是forkJoin
,因为每个这些Observable都是冷的且有限的,并且forkJoin
捕获每个Observable的第一个发射,并在所有观测值完成时发射所有值:
const original = forkJoin([
this.http.get('https://jsonplaceholder.typicode.com/todos/11'),
this.http.get('https://jsonplaceholder.typicode.com/todos/22'),
this.http.get('https://jsonplaceholder.typicode.com/todos/33')
]);
let result = {a: null, b: null, c: null};
original.subscribe([a,b,c] => result = {a,b,c});
请注意,forkJoin
发出的项将是一个数组,其索引与传入的Observable的索引匹配。
答案 2 :(得分:1)
如果源对象已经包含Observables,则可以像下面这样进行操作(显然有多种方法可以做到):
const mockXHRCall = (url: string) => {
return of('response');
};
const original = of({
a: mockXHRCall('https://jsonplaceholder.typicode.com/todos/11'),
b: mockXHRCall('https://jsonplaceholder.typicode.com/todos/22'),
c: mockXHRCall('https://jsonplaceholder.typicode.com/todos/33')
}).pipe(
mergeMap(obj => {
const observables$ = Object.keys(obj).map(key => obj[key].pipe(
map(response => (
{ [key]: response } // wrap the response with eg. { c: ResponseFromC }
)),
));
return merge(...observables$);
}),
scan((acc, wrapped) => (
{ ...acc, ...wrapped }
), {}),
takeLast(1),
).subscribe(console.log);
scan
收集所有响应并将它们合并为一个对象。