My task: I have a file that contains many items and each item is related to an array of URLs of images which I need to download. I want to download all of the links, I'm using this library for the image downloading and I'm using promises.
The problem: The problem occurs when I start to download many images from many items, the program sends more than 4000 requests before the first one finished and the program crashes.
My solution: My idea was to only handle about 2 items at a time so that I'm downloading about 20 images at a time. I've tried all sorts of variations with promises and async functions but I'm pretty new to those so my attempts failed.
My code flow is something like this:
csvRun()
function csvRun(){
for(let i = 1; i <= itemsAmount; i++){ // Loops over the items
// I want to be able to run only x items at a time
console.log('Item number ' + i)
itemHandle()
}
}
function itemHandle(){ // This function seems useless here but since the item has more data I kept it here
handleImages()
}
function handleImages(){ // Loops over the images of the item
for(let g = 0; g < imagesAmount; g++){
// Here there is a promise that downloads images
// For the example I'll use settimout
setTimeout(() => {
console.log('Image downloaded ' + g)
}, 3000);
/** If you want the error just use ImgDonwload instead of
settimeout and set imagesAmount to 20 and itemsAmount
to 400
*/
}
}
// Only here to recreate the error. Not necessarily relevant.
function ImgDownload(){
var download = require('image-downloader')
download // returns the promise so the handling could resume in order
.image({
url:
"https://cdn.vox-cdn.com/thumbor/XKPu8Ylce2Cq6yi_pgyLyw80vb4=/0x0:1920x1080/1200x800/filters:focal(807x387:1113x693)/cdn.vox-cdn.com/uploads/chorus_image/image/63380914/PIA16695_large.0.jpg",
dest: "/folder/img.jpg"
})
.then(({ filename, image }) => {
console.log("File saved to", filename);
})
.catch((err: Error) => {
console.error(err);
});
}
Currently, the code finishes the loop in csvRun
and prints out Item number 1
up to Item number {itemsAmount}
and after 3 seconds prints out all of the Image downloaded messages
. I understand why that happens. I want to change the code so that each time only 2 calls to itemHandle
are being made simultaneously.