Q:

How to manage multiple promises

I'm writing a crawler using node.js.  At first, I need to fetch the main page to get the URL of each item on that page, then I crawl URL of each item to get details of them one-by-one
fetchPage(url) is to get HTML text of a link
function fetchPage(url){
    return new Promise(
        (resolve,reject)=>{
            agent
            .get(url)
            .end(function(err,res){
                if (err){
                    reject(err);
                } else{
                    resolve(res.text);
                }
            });
        });
}

This is the global call of this crawler
fetchPage(link).then(
    (result)=>{
        const urls=getUrls(result);
        for (var i=0;i<5;i++){
            fetchItem(urls[i].link).then(
                (result)=>{
                    console.log('Done');
                },
                (error)=>console.log(error)
            );
        }
    },
    (error)=>console.log(error)
);

I processed to get the URLs of all items after fetching the main page (via getUrls)
fetchItem(url) is another Promise that ensures every HTML text of an item should be processed via getItem after being fetched by fetchPage
function fetchItem(url){
    return new Promise(
        (resolve,reject)=>{
            fetchPage(url).then(
                (result)=>{
                    getItem(result);
                },
                (error)=>reject(error)
            );
        });
}

It does crawl.  It does get all items I need without any lack of information. 
But there's something wrong with my code.  Why doesn't the console log Done message for me? 
Results are not in the right order.  The order of crawled results is not as I expected, it is different from the order on the website. 
Please point out what have I misunderstood and done wrong with these asynchronous control?  How to ensure the order of them?  How to fix this code to meet? 
How should I do if I want to log a message All done after all items are completely crawled, making sure they're completely fetched in correct order? 

A:

Done is not getting called because you are not resolving the Promise created in fetchItem function. 
I guess to maintain the order of results, you might want to use Promise.all.  It will also help in getting All done message when all items are completely crawled. 
I will start with changing fetchPage function by converting urls to a array of fetchItem promises using map that I can pass to Promise.all.  Something like this
fetchPage(link).then(
    (result)=>{
        const urls=getUrls(result);
        var promises = urls.map((url) => fetchItem(url.link));
        Promise.all(promises).then((values) => { 
            console.log('All done'); 
            console.log(values); 
        }, (error) => { 
            console.log(error); 
        });
    },
    (error)=>console.log(error)
);

then adding resolve to your fetchItem method. 
function fetchItem(url){
    return new Promise(
        (resolve,reject)=>{
            fetchPage(url).then(
                (result)=>{
                    resolve(getItem(result));
                },
                (error)=>reject(error)
            );
    });
}

