【发布时间】:2018-09-20 00:02:32
【问题描述】:
我必须小批量获取数据以完成我在前端已有的数据, 因此,假设我有数百个 id、name 和其他字段为空的对象,因为我必须通过传递 id 从另一个端点获取它们,但是,这个另一个端点非常慢,我需要为在“不中断任何其他请求”的情况下,在后台说 5。
最好的方法是什么?并将获取的数据附加到对象列表中的相应项目?
【问题讨论】:
我必须小批量获取数据以完成我在前端已有的数据, 因此,假设我有数百个 id、name 和其他字段为空的对象,因为我必须通过传递 id 从另一个端点获取它们,但是,这个另一个端点非常慢,我需要为在“不中断任何其他请求”的情况下,在后台说 5。
最好的方法是什么?并将获取的数据附加到对象列表中的相应项目?
【问题讨论】:
如果我理解正确,您可以从一组您知道 id 和 name 的对象开始。您需要使用可以使用慢速 API 获取的附加数据填充所有这些对象,因此您不希望一次发出超过 5 个此类请求。
假设此类 API 的调用是通过方法 getDataForId(id) 实现的,并且使用从 API 检索到的附加数据填充对象是由方法 populate(obj, data) 执行的,其中 obj 是必须填充,data 是用于填充对象的原始数据。
如果没问题,您可以考虑采用这些方法
const objArray = [
{id: 123, name: 'first'},
{id: 456, name: 'second'},
......
{id: xyz, name: 'last'},
];
from(objArray).pipe(
mergeMap(
obj => getDataForId(objArray.id).pipe(
map(data => populate(obj, data))
), 5
)
)
.subscribe()
替代实现 - 在评论之后
您也可以考虑从后端获取列表,然后以 5 个为一组获取包含完整详细信息的项目。您可以使用如下代码实现此目的
getListOfIds().pipe(
bufferCount(5),
map(arrayOf5Ids => getDataForId(objArray.id).pipe(
map(data => populate(obj, data))
)),
switchMap(arrayOf5Observables => forkJoin(arrayOfObservables)),
)
.subscribe(arrayOf5Items => // do what you want}
【讨论】:
getListOfIds().pipe(filter(obj => // your filter logic), bufferCount(5), .....)一样使用filter
你可以像这样使用mergeMap
this.http.get('/api1').pipe(
mergeMap(character => this.http.get('/api2'))
).subscribe(() => {
....
});
【讨论】: