我正在尝试通过队列进行图像上传。目前,我需要通过五个上传图像
例如,如果我有10个图像,我需要上传5个图像,当这5个图像将被上传时,我需要对剩余的5个图像进行另一个请求。
经过大量的搜索和测试,我可以通过(concat
-RXJS函数(和(scan
和last
-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] }),
{}
))
);
}