I have a TypeScript function that tries to download a large number of small documents concurrently. Here’s the code:
const bulkDownload = async (analyses: FullAnalysesResponse[]) => {
setIsLoading(true);
const promises = analyses.map(async (analysis) => {
const documentInfo = await getDocumentInfo({ documentId: analysis.downloadFileId! });
const attachment = await downloadDocument({ documentId: analysis.downloadFileId! });
FileSaver.saveAs(new File([attachment], documentInfo.name, { type: documentInfo.mimeType }));
});
const results = await Promise.allSettled(promises);
setIsLoading(false);
results.forEach((result, index) => {
const analysisSerialNumber = analyses[index].deviceSerialNumber;
result.status === 'fulfilled'
? successfulQueries.push(analysisSerialNumber)
: failedQueries.push(analysisSerialNumber);
});
return { failedQueries, successfulQueries };
};
The issue is that when I trigger this function to download multiple files at once, not all the files are downloaded. The number of downloaded files changes every time I run the function, and I never get all the files. All the API calls are working, so all the promises are successful. The issue seems to come from the FileSaver.saveAs
function.
I also tried a version that uses a simple for...of
loop, which works fine:
const bulkDownload = async (analyses: FullAnalysesResponse[]) => {
setIsLoading(true);
const successfulQueries: string[] = [];
const failedQueries: string[] = [];
for (const analysis of analyses) {
try {
const documentInfo = await getDocumentInfo({ documentId: analysis.downloadFileId! });
const attachment = await downloadDocument({ documentId: analysis.downloadFileId! });
FileSaver.saveAs(new File([attachment], documentInfo.name, { type: documentInfo.mimeType }));
successfulQueries.push(analysis.deviceSerialNumber);
} catch (error) {
failedQueries.push(analysis.deviceSerialNumber);
}
}
setIsLoading(false);
return { failedQueries, successfulQueries };
};
The for...of
version works reliably but is slower since it downloads the files sequentially. I would like to understand why the first (concurrent) function is not working as expected. I assumed that running the downloads concurrently would be more efficient.
Any insights on why this happens, and how to fix it while keeping the performance benefits of concurrent downloads?