0

I'm having problem calling async function inside a while loop.

the problem is 'while' statement will end before its underlying function result appear and thats because it's async function. the code is like below:

while (end < min) {
  db.collection('products').count({
      tags: {
        $in: ['tech']
      }
    }, function(err, result) {
      if (result) {
        a = result;
      }
    });
  max = min;
  min = max - step;
  myitems.push(a);
}
res.send(myitems);

and at the end i could not send the result because all of while iteration should finish before sending the final result. how could i modify the code to solve such a problem?

thanks in advance

3
  • Are you trying to send your requests one at a time, where the next request isn't sent until the previous one has finished? And, then you want to do res.send() when they are all done? Or, are you fine sending all the requests at once and you just want to know when they are all done? FYI, in case you hadn't realized it, you can't use a while loop and expect it to "wait" for async operations to be done. You will have to iterate a different way, but which method depends upon some details of your operation (thus the questions I've asked). Commented Aug 22, 2015 at 18:28
  • What are max, min, end and step all used for? They don't seem to be used in the request at all and all your db.collection() requests appear to be identical. There appears to be some missing code that is relevant. Commented Aug 22, 2015 at 18:30
  • no I want my db.count operation execute one by one and after executing all of them i put them in an array and send the result to the client. min max and end is used to end the while operation. these are variable that i used to find how many iteration should i have Commented Aug 22, 2015 at 18:45

2 Answers 2

1

Without using third party libraries, here's a method of manually sequencing your async operations. Note, because this is async, you have to process the results inside of the next() function when you see that you are done iterating.

// assume that end, max, min and step are all defined and initialized before this
var results = [];
function next() {
    if (end < min) {
        // something seems missing from the code here because
        // this db.collection() call is always the same
        db.collection('products').count({tags: {$in: ['tech']}}, function(err, result)  {
            if (!err && result) {
                results.push(result);
                max = min;
                min - max - step;
                next();
            } else {
                // got an error or a missing result here, provide error response
                console.log("db.collection() error or missing result");
            }
        }
    } else {
        // all operations are done now
        // process the results array
        res.send(results);
    }
}

// launch the first iteration
next();
Sign up to request clarification or add additional context in comments.

Comments

0

You could leverage a 3rd party library to do this as well (non working performQuery example using async):

function performQuery(range, callback) {
  // the caller could pre calculate 
  // the range of products to retrieve
  db.collection('products').count({
      tags: {
        $in: ['tech'],
        // could have some sort of range query
        $gte: range.min,
        $lt: range.max
      }
    }, function(err, result) {
      if (result) {
        callback(result)
      }
    });
}

async.parallel([
    performQuery.bind(null, {min: 0, max: 10}),
    performQuery.bind(null, {min: 10, max: 20})
], function(err, results) {
   res.send(results);
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.