I'm writing a bulk downloader for node.js and trying to understand bluebird promises.
I want to limit the number of parallel requests and disk writes.
As I understand it, Promise.map()
with {concurrent: }
should do what I want.
Because pipe()
and http.get()
can't automatically be promisified, I'm trying to use custom promises.
But I don't fully understand the then()
mechanism.
To me, it sounds like the returned promise should only be fulfilled when the whole chain has been fulfilled.
However, in my code only the first promise in the chain appears to be waited for by map()
, and many request and disk writes happen in parallel.
import Promise from 'bluebird';
import fs from 'fs';
import https from 'https';
Promise.promisifyAll(fs);
Promise.map(Images, image => {
console.log("Opening image " + image.id);
let file = fs.createWriteStream(dir + '/' + image.id + '.jpg');
return new Promise((resolve, reject) => {
console.log("Downloading image " + image.id);
https.get(image.url, resolve).on("error", reject);
})
.then(response => {
response.pipe(file);
console.log("Saving image " + image.id);
return new Promise((resolve, reject) => {
file.on("finish", resolve);
file.on("error", reject);
});
})
.then(() => {
console.log("Finished writing image " + image.id);
file.close();
})
.catch(e => {
console.log("Error during image save of " + image.id + ": " + e.code)
});
}, {concurrent: 50})
.then(res => {
console.log("Finished writing all images")
})
.catch(e => {
console.log("Some images failed to be written: " + e.code)
});
}
What am I doing wrong? Can you help me understand the flow of promise fulfillment and rejection?