最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to wait for all async tasks to finish in Node.js? - Stack Overflow

programmeradmin0浏览0评论

My program needs to run many async tasks.

And one task must run when all async tasks complete.

How can I make this function to wait all async functions?

let urls=[....]

for(var i=0; i<urls.length; i++){
    doRequest(urls[i])
}
finish()



function doRequest(url){
    request({
      uri: url,
    }, function(error, response, body) {
        //do some tasks
    });
}

function finish(){
    console.log('finish')
}

My program needs to run many async tasks.

And one task must run when all async tasks complete.

How can I make this function to wait all async functions?

let urls=[....]

for(var i=0; i<urls.length; i++){
    doRequest(urls[i])
}
finish()



function doRequest(url){
    request({
      uri: url,
    }, function(error, response, body) {
        //do some tasks
    });
}

function finish(){
    console.log('finish')
}
Share Improve this question edited Mar 30, 2017 at 22:55 Talha Awan 4,6194 gold badges26 silver badges40 bronze badges asked Mar 30, 2017 at 20:35 CL SoCL So 3,75911 gold badges57 silver badges101 bronze badges 4
  • 4 Promise.all() – zerkms Commented Mar 30, 2017 at 20:36
  • ^ works well in conjunction with Bluebirds Promisifyall for nodeback api's that don't return a promise. – rlemon Commented Mar 30, 2017 at 20:38
  • pass in i to doRequest, along with length and compare on each callback. – Joe Lissner Commented Mar 30, 2017 at 20:46
  • You could checkout async.waterfall, though there a few to choose from based on what you may need: informit.com/articles/article.aspx?p=2265406&seqNum=2 – reedb89 Commented Mar 30, 2017 at 20:54
Add a comment  | 

2 Answers 2

Reset to default 13

Promise are exactly what you need. They're native in JS nowadays, no need for extra libraries.

function finish () {
    console.log("finish");
}

function doRequest (uri) {
    // wrap code in promise
    return new Promise((resolve, reject) => {
        request(
            { uri },
            (error, response, body) => {
                if (error) {
                    // error case, similar to "throw"
                    reject(error);
                }
                else {
                    // success case, similar to "return"
                    resolve({ response, body });
                }
            }
        );
    });
}

let urls=[...];

// Basic way to do it:
Promise.all(urls.map(doRequest)).then(finish);

// async/await notation:
// you must be in an "async" environement to use "await"
async function wrapper () {
    await Promise.all(urls.map(doRequest));
    finish();
}
// async function return a promise transparently
wrapper();

The easiest solution that doesn't require rewriting everything using promises, would be to check the number of completed requests at the end of doRequest function, and call finish if all requests have been completed.

let urls=[....]
let completed = 0

for(var i=0; i<urls.length; i++){
    doRequest(urls[i])
}

function doRequest(url){
    request({
        uri: url,
    }, function(error, response, body) {
        //do some tasks

        completed++
        if (completed === urls.length) {
            finish()
        }
    });
}

function finish(){
    console.log('finish')
}
发布评论

评论列表(0)

  1. 暂无评论