如何在要解析的嵌套对象数组中获取 RxJs Observable 的值?
How can I get value of RxJs Observable in a nested array of objects to resolve?
我目前正在请求 returns 某些文件和用户的数据。
对于每个文件,我想 return 一个包含数据的对象,但其中一个键依赖于另一个请求。
如何发出此请求,以便 getData
函数等待内部可观察值解析为一个值?
function getData() {
return forkJoin([
filesApiRequest),
userApiRquest
])
.pipe(map(([files, userInfo]) => {
return files.getFilesList()
.map((file) => {
const name = file.getName();
const importantInfo = importantInfoCall(userInfo.name, name); // returns an observable.
// How can I get the value from this before returning? I need this piece of data for each
// file in the files list.
return {
data1,
data2,
name,
...,
hasImportantInfo: importantInfo
};
})
}));
}
您需要使用“高阶映射运算符”(switchMap
),它将订阅您的内部可观察源并发出您需要的数据。在您的情况下,您需要进行多次调用(每个文件一个调用),因此您可以将文件列表映射到发出所需数据的可观察对象数组。您可以再次使用 forkJoin
将所有这些调用包装到一个单独的可观察对象中:
function getData() {
return forkJoin([filesApiRequest, userApiRquest]).pipe(
switchMap(([files, userInfo]) => forkJoin(
// return array of observables
files.getFilesList().map(f => toDataWithImportantInfo$(f, userInfo))
))
);
}
function toDataWithImportantInfo$(file, userInfo) {
const name = file.getname();
return importantInfoCall(userInfo.name, name).pipe(
map(importantInfo => ({
data1,
data2,
name,
...,
hasImportantInfo: importantInfo
})
);
}
当您有大量请求时,forkJoin
不是最佳解决方案,因为它会同时执行所有请求(也许您不想开始一次 500 个 http 请求).
为了限制请求的数量,我们可以使用merge
代替,因为它提供了一个并发参数:
function getData() {
return forkJoin([filesApiRequest, userApiRquest]).pipe(
switchMap(([files, userInfo]) => merge(
files.getFilesList().map(f => toDataWithImportantInfo$(f, userInfo))
, 5)), // MAX 5 CONCURRENT
toArray()
);
}
forkJoin
在所有源完成时发出所有结果的数组。 merge
单独发出每个结果,因此如果您想在所有内部源完成后发出单个数组(而不是单独发出),则需要 toArray
。
我目前正在请求 returns 某些文件和用户的数据。
对于每个文件,我想 return 一个包含数据的对象,但其中一个键依赖于另一个请求。
如何发出此请求,以便 getData
函数等待内部可观察值解析为一个值?
function getData() {
return forkJoin([
filesApiRequest),
userApiRquest
])
.pipe(map(([files, userInfo]) => {
return files.getFilesList()
.map((file) => {
const name = file.getName();
const importantInfo = importantInfoCall(userInfo.name, name); // returns an observable.
// How can I get the value from this before returning? I need this piece of data for each
// file in the files list.
return {
data1,
data2,
name,
...,
hasImportantInfo: importantInfo
};
})
}));
}
您需要使用“高阶映射运算符”(switchMap
),它将订阅您的内部可观察源并发出您需要的数据。在您的情况下,您需要进行多次调用(每个文件一个调用),因此您可以将文件列表映射到发出所需数据的可观察对象数组。您可以再次使用 forkJoin
将所有这些调用包装到一个单独的可观察对象中:
function getData() {
return forkJoin([filesApiRequest, userApiRquest]).pipe(
switchMap(([files, userInfo]) => forkJoin(
// return array of observables
files.getFilesList().map(f => toDataWithImportantInfo$(f, userInfo))
))
);
}
function toDataWithImportantInfo$(file, userInfo) {
const name = file.getname();
return importantInfoCall(userInfo.name, name).pipe(
map(importantInfo => ({
data1,
data2,
name,
...,
hasImportantInfo: importantInfo
})
);
}
当您有大量请求时,
forkJoin
不是最佳解决方案,因为它会同时执行所有请求(也许您不想开始一次 500 个 http 请求).
为了限制请求的数量,我们可以使用merge
代替,因为它提供了一个并发参数:
function getData() {
return forkJoin([filesApiRequest, userApiRquest]).pipe(
switchMap(([files, userInfo]) => merge(
files.getFilesList().map(f => toDataWithImportantInfo$(f, userInfo))
, 5)), // MAX 5 CONCURRENT
toArray()
);
}
forkJoin
在所有源完成时发出所有结果的数组。 merge
单独发出每个结果,因此如果您想在所有内部源完成后发出单个数组(而不是单独发出),则需要 toArray
。