Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
135 views
in Technique[技术] by (71.8m points)

javascript - NODE.JS - How to invoke correctly next() after multi REQUESTS are done?

I am running over an ARRAY using forEach() loop. For every element , I need to invoke a request. I want to call the next() after ALL invoked requests are done (assume I have at least a 100 requests to invoke).

Any ideas how to approach this?

Here is a little sample code to demonstrate my question -

var arr = ["A" , "B", "C" , "D" , "E"];
arr.forEach(function (arrayItem) {
	var options = { 
        method: 'GET',
        url:"some_url",
        headers: {...} 
  };
  request(options, function (error, response, body)
  {
    if (error)  {next(error);}

    // DO_SOMETHING based on arrayItem

  }); // end of request()
});  //end of forEach

// WHERE should I place the next()?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are a couple ways you can do this. Since all the calls to request() are asynchronous and thus will finish sometime in the future long after your loop has finished, you will have to keep track of them somehow. I'll show two methods, one using Promises and one using a counter.

Promises

// create wrapper function that returns a promise
function requestPromise(options) {
    return new Promise(function(resolve, reject) {
        request(options, function(error, response, body) {
            if (error) return reject(error);
            resolve({response: response, body: body});
        });
    });
}

var arr = ["A" , "B", "C" , "D" , "E"];

Promise.all(arr.map(function(item) {
    // create options object here for each request
    var options = { 
        method: 'GET',
        url:"some_url",
        headers: {...} 
    };

    return requestPromise(options);

})).then(function(results) {
    // process results here

    // call next() here because all processing is now done
    next();
}).catch(function(err) {
    // error happened
    next(err);
});

Manual Counter

var arr = ["A" , "B", "C" , "D" , "E"];
var errDone = false;
var cntr = 0;
arr.forEach(function (arrayItem) {
    var options = { 
        method: 'GET',
        url:"some_url",
        headers: {...} 
  };
  request(options, function (error, response, body) {
    if (error)  {
        if (!errDone) {
            // latch error so we don't call next(error) multiple times
            errDone = true;
            next(error);
        }
    } else {
        // process result here

        // check if this is the last response
        ++cntr;
        if (cntr === arr.length) {
            // all responses done here
            next();
        }
    }
  });

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...