srdg
srdg

Reputation: 595

Why do node.js promises not resolve even when put in then() block?

I want to get the following workflow:

After a lot of tinkering, my code looks like this -

nightmare 
    .goto(url) 
    .wait('body') 
    .evaluate( ()=>document.querySelector('body').innerHTML) 
    .end() 
    .then((response) => { 
        return getJSONData(response);
    })
    .then((data) => {
        return processJSONData(data);
    })
    .then((pages) => {
        return createFile(pages);
    }) 
    .catch(err => { 
        console.log(err);  
    });

getJSONData(data) uses cheerio to parse the HTML, and processJSONData(data) uses image-downloader to download the images. From my understanding, since this is a promise chain, it means the execution inside each then() will be asynchronous, but the then() blocks themselves will be executed sequentially. On running the code, I see that even though the first two then() blocks are executed sequentially (up to now), the createFile(pages) block is executed immediately thereby creating a corrupt PDF file. What could possibly be the reason behind this? How can I ensure that the then() blocks are executed synchronously, i.e. each then() runs only after the previous then is resolved?
The complete code can be found here.

Upvotes: 2

Views: 170

Answers (1)

Sirko
Sirko

Reputation: 74076

You do not wait for all async operations to finish within processJSONData(), but only for some parts of them. Consider changing as follows:

function processJSONData(data){

    // map() instead of forEach() to get a promise per request
    const reqs = data.map(element => {
        // return the inner promise chain to be collected
        return download.image(element)
        .then( ({filename}) => {
            console.log("Saved to ",filename); 
            return filename;
        });
    });

    // return a promise that waits for all of them to be finished
    return Promise.all( reqs );

}

Upvotes: 1

Related Questions