因此,问题在于我有大量的对象,假设我需要以NGRX效果发送给我们的API,然后派遣与响应的新操作,但是API花费的时间太长来处理如此大的请求。有一次,所以我想将这个数组分成较小的块,然后将每个数组接一个地发送一个请求,然后将所有响应从所有响应结合到一个动作中。我已经尝试将这些大量数据映射到带有() operator的 的一系列可观察结果中,但是在映射之后无法弄清楚接下来要使用的是什么,我尝试了铸造它可以承诺并使用Promise.all(),但再次没有运气。总而言之,我需要做的是:
- 操作触发了一个效果,需要将API调用带有动作中的一系列数据发送,
- 从而将一系列数据分为100个对象的块,
- 这些块被映射到API请求中,一个接一个地发送,每个请求都需要与先前的响应与先前的响应结合在一起,
- 在完成所有这些请求之后,需要派遣带有合并响应的操作才能更新存储。
这是我当前正在使用的简化效果,我需要分割的是 action.rows
:
loadRows$ = createEffect(() => {
return this.actions$.pipe(
ofType(RowsActions.LoadRows),
switchMap((action) => {
return this.eventsService.getBatchRows(action.rows).pipe(
switchMap((response) => {
return [
new RowsLoaded({ rows: response.rows }),
new LoadedTableData(response.rows),
];
}),
catchError(() => {
return of(new RowsFailedToLoad());
})
);
})
);
});
So the problem is that I have a large array of objects, let's say a 1000 that I need to send to our API in NGRX Effect and then dispatch a new Action with the response, but API takes too long to process such a large requests at once, so I want to divide this array into smaller chunks, send a request with each of them one after another and then combine responses from all of them into a single action. I've tried it with mapping this large array of data into an array of Observables with from()
operator, but couldn't figure out what to use next after it was mapped, I've tried casting it to Promises and use Promise.all() on them but again, no luck. In summary what I need to do is this:
- Action triggers an Effect that needs to send API call with an array of data from Action,
- In the Effect, array of data gets divided into chunks of 100 objects,
- These chunks are mapped into API requests, sent one after another, and the response from each needs to be combined with previous ones,
- After all of these requests are done, an Action with the combined response from them needs to be dispatched to update Store.
Here is a simplified Effect that I'm using currently and what I need to divide is action.rows
:
loadRows$ = createEffect(() => {
return this.actions$.pipe(
ofType(RowsActions.LoadRows),
switchMap((action) => {
return this.eventsService.getBatchRows(action.rows).pipe(
switchMap((response) => {
return [
new RowsLoaded({ rows: response.rows }),
new LoadedTableData(response.rows),
];
}),
catchError(() => {
return of(new RowsFailedToLoad());
})
);
})
);
});
发布评论
评论(1)
已经实现了相似逻辑,
如果一个块将有100件物品 - 仍然很大。
我正在运行所有Paralelly的物品。
upd:
如果您将更改
Mergemap
concatmap - 所有调用将为序列这里的单行或一块行
是有效的示例:
最终版本:
使用块方式 - 几乎没有什么可用的方法
将
在此处使用和使用:
have implemented similiar logic,
if one chunk will have 100 items - it still to big number.
I am running ALL items paralelly.
UPD:
if you will change
mergeMap
toconcatMap
- all calls will be sequentialit does not matter if it is single row or chunk of rows
here is working example: https://codesandbox.io/s/rxjs-playground-forked-u8c7jd?file=/src/index.js
FINAL VERSION:
to use chunk way - almost nothing to do
will use
and use here: