Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to wait for all async tasks to finish in Node.js?

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')
}
like image 862
CL So Avatar asked Dec 04 '22 22:12

CL So


2 Answers

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();
like image 139
Kulvar Avatar answered Dec 11 '22 16:12

Kulvar


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')
}
like image 24
danroshko Avatar answered Dec 11 '22 17:12

danroshko