RXJS:按队列的请求-ForkJoin



我正在尝试通过队列进行图像上传。目前,我需要通过五个上传图像

例如,如果我有10个图像,我需要上传5个图像,当这5个图像将被上传时,我需要对剩余的5个图像进行另一个请求。

经过大量的搜索和测试,我可以通过(concat-RXJS函数(和(scanlast-RXJS运算符(找到这个解决方案:

在index.html中

// added chunk function into array protptype
Array.prototype.chunk = function (chunkSize) {
var R = [];
for (var i = 0; i < this.length; i += chunkSize) {
R.push(this.slice(i, i + chunkSize));
}
return R;
}

在服务中


uploadImages(images: File[]) {
const requestsList = images.map(file => {
return this._baseAPI.filesManagement.uploadFile({ file, 'image' })
});
// custom function: added manualy in index.html
const requestChunks = requestsList.chunk(5);  

const requestsByChunks = requestChunks.map(reqs => forkJoin(reqs));
return concat(...requestsByChunks).pipe(
// transforming and collecting all of the responses
scan((acc, response: {folder: string; image: string}[]) => {
response.forEach(itemResponse => {
if (!acc[itemResponse.folder]) { acc[itemResponse.folder] = []; }
acc[itemResponse.folder].push(itemResponse.image);
});
return acc;
},
{} as { [key: string]: string }),
// getting the callected response only once at the end
last()
);
}

用法示例

this.uploadImages(/* Array of files*/).subscribe(response => {console.log(response); })

我想知道,对于这些情况,还有其他解决方案或最佳实践吗。也许我错过了什么,因为我不确定这是最好的解决方案?

此外:以下是电流逻辑的模拟:https://stackblitz.com/edit/rxjs-kcnrgn?file=index.ts

感谢大家抽出时间。

以下是我如何在深入研究RxJS和不可变对象/数组的同时做到这一点。

可能需要一些调整,因为我并没有真正测试这个。这基本上和你正在做的一样。

uploadImages(images: File[]) {
return from(images).pipe(
map(file => this._baseAPI.filesManagement.uploadFile({ file, 'image' })),
// chunk 5
bufferCount(5), 
// perform the requests 5 at a time
concatMap(reqs => forkJoin(reqs)), 
// like last, but creates an array of emissions (which are themselves arrays of size 5)
toArray(), 
// Flatten the array of arrays into a single array with all the results
map(arr => arr.flat()),
// transforming all of the responses
map(res => res.reduce((
acc: { [key: string]: string[] }, 
{folder, image}: { folder: string; image: string }
) => ({...acc, folder: [...acc[folder] || [], image] }),
{}
))
);
}

最新更新