1

I'm somewhat new to javascript. Recently, I've been working on a node.js project, and I came across the problem of asynchronous callbacks in javascript. My code is below:

So ideally, I would like the request method to be caried out, THEN the callback from the res.on('data') event to be executed, and finally have callback for the .each() iterator to be called. Unfortunately, the asynchronous nature of javascript causes the program to exit the main code block even before the first callback is executed.

var req = https.request(options, function(res) {
  // console.log("statusCode: ", res.statusCode);
  // console.log("headers: ", res.headers);
  console.log('1st call back exec');
  res.on('data', function(d) {
    console.log('2st call back exec');
    var $ = cheerio.load(d);

    //traversing method

    $('.dddefault').each(function(i){
        console.log('3st call back exec');

        if(i == 3){
            remainingSeats = parseInt($(this).text().trim());
            console.log('inner0:'+remainingSeats);
            return;
        }

    });

    console.log('inner1:'+remainingSeats);
  });
  console.log('inner2:'+remainingSeats);
});

req.end();

req.on('error', function(e) {
  console.error(e);
});

Can anyone point me in the right direction to get my code working in the way I had intended it to work? Thanks.

1

1 Answer 1

2

It shouldn't abruptly stop unless you get an unhandled error. And, chances are, that error would probably be from cheerio as you may not be giving it the entire document to try to parse.

Note: The req.on('error', ...) callback only receives errors that http or req throw. It won't catch errors from cheerio.

res is a Stream, so it won't necessarily arrive in a single chunk of 'data'. You'll want to collect any number of chunks that may arrive and work with the combined result once the stream has come to an 'end'.

var req = https.request(options, function(res) {
    var body = [];

    res.setEncoding('utf8');

    res.on('data', function (chunk) {
        body.push(chunk);
    });

    res.on('end', function () {
        body = body.join('');

        var $ = cheerio.load(body);

        // etc.
    });

You may also consider using request, which handles consuming the stream for you:

request(options, function (err, res, body) {
    var $ = cheerio.load(body);

    // etc.
});
Sign up to request clarification or add additional context in comments.

1 Comment

hey thank you for your response, this actually helped me solve another problem I was having (inconsistent data reads), but the problem in my post was more of a flow control issue. Although, I think I figured it out, I can just call another callback inside the innermost callback, and I should be fine. Thanks for pointing out response is a stream though!

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.