0

I am using express and async.js for a node application. I have this code in my app.js:

var resultObject = {};

app.get('/average', function(req, res) {
  async.series([
    function(callback) {
  //This does some complex computations and updates the resultObject
      routes.avg(req.query.url, resultObject);
      console.log('1');
      callback();
    }
    ,
    function(callback) { 
      res.send(resultObject);
      console.log('2');
      callback();
    }
  ]);
});

The problem is that the res.send(...) fires before the complex computation in the first function finishes. Therefore, the object sent is empty. Is there some error in my code, or am I not using async.js correctly?

4
  • according to the code you pasted, resultObject would be empty anyway, unless routes.avg modifies it. do you have the rest of your code available? It doesn't seem plausible that the methods are being executed out of order. Commented Jul 24, 2013 at 14:31
  • That's exactly what it does, it modifies the resultObject. The problem is that the res.send() fires before the function that modifies the object has finished its calculations. Commented Jul 24, 2013 at 14:37
  • is routes.avg an asynchronous method? Commented Jul 24, 2013 at 14:39
  • Yes. I wonder if the problem is that the method is exported and not called directly in app.js with a callback. Commented Jul 24, 2013 at 14:58

2 Answers 2

1

According to your comments, the problem is that your routes.avg method is asynchronous. This means that the method gets executed but doesn't block the program from continuing, which means that the 2nd closure in your series is being called almost immediately after the 1st one.

The problem isn't that the closures in the async.series call are being called out of order, it's that there's nothing that keeps your callback in closure 1 from being executed before routes.avg is finished.

To fix this, you could pass your callback into your routes.avg call, and edit the routes.avg method so that it calls the callback closure when all the calculation is done. That way, the 2nd closure in your series will not be executed until the callback passed to closure 1 is called by the routes.avg method.

If you don't have access to change the routes.avg method, then you have to find another way to detect when it's done it's work before you call the callback param passed to closure 1 from async.

Sign up to request clarification or add additional context in comments.

Comments

0

Perhaps try something like this:

async.series([
  function(callback) {
    routes.avg(req.query.url, resultObject);
    console.log('1');
    callback();
  },
  function(callback) { 
    console.log('2');
    callback();
  }
],
function(err, results){
   if(!err)
     res.send(resultObject);
   else
     //do something here for error?
});

1 Comment

There would be no use for invoking the second function at all then. Plus, this doesn't work, the behavious is still that which I described above.

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.