2

EDIT: I want to explain the problem more clearly, my purpose is to make http response before "webot.waitRule()" returns. So should http request call back to webot.waitRule or the other way around?

below is my code which implements a module in a program, and my problem is the function returns before the http request get its response. I know http requests in node js is async, so there is any solution for it? I am pretty new in javascript and nodejs. Thanks.

 webot.waitRule('wait_class', function(info) {
    var courseName='lol';
     var options = {
        host: 'api.uwaterloo.ca',
        path: '/v2/courses/CS/486/examschedule.json'
      };
      callback = function(response) {
          var str = '';
  //another chunk of data has been recieved, so append it to `str`
          response.on('data', function (chunk) {
          str += chunk;
        });
          response.on('end',function(){
        // console.log(str);
         // return "kkk";
         var data = JSON.parse(str);
         console.log(data['data']['course']);
         courseName = courseName+data['data']['course'];
         console.log("finished");
         // return "lolllll";
         // return "nide ke shi "+ courseName;
      });
    }
    var req = http.request(options, callback);
    req.end();
    console.log("i am finshed");
     return courseName;
  });
Yellow
  • 23
  • 1
  • 4
  • return makes no sense in async functions... it should say "finished" when done no? – dandavis Mar 19 '14 at 21:20
  • 1
    notice that `callback` is global... – Bergi Mar 19 '14 at 21:20
  • You need to use the callback. It looks like you've started to do that, so I'm not really sure where the problem is. – Brad Mar 19 '14 at 21:20
  • 1
    This is a dup of hundreds of other questions about returning data from a function that uses async calls. Marked as dup. – jfriend00 Mar 19 '14 at 21:24
  • First, using return in asynchronous environment is not a good practice at all. You should replace the return with a better design, such as module pattern. That way, you can have courseName variable available to the module. As a side note, you may use Async.js series function to sync between function calls. – aadel Mar 19 '14 at 21:53
  • @Bergi so I want to explain the problem more clearly, my purpose is to make http response before "webot.waitRule()" returns. So should http request call back to webot.waitRule or the other way around? – Yellow Mar 19 '14 at 22:03

1 Answers1

0

Since node is primarily asynchronous and uses callbacks (as opposed to promises), you'd likely want to define a function that will be called that takes a parameter which is the output of your asynchronous call.

For example (in your case): you get courseName in the callback for response.on('end', .... You could define a function such as:

function processCourseName(name) {
    console.log('do something with', name);
}

And then after console.log('finished');, just add a call to that method

...
courseName = ...
console.log("finished");
processCourseName(courseName); //whenever the request is finished, then process the course name in a separate function

More explanation: Your return courseName statement are exiting from the function before the http.request call is finished, and therefore before courseName is even assigned to a proper value.

More edit: I took a look at the webot module and it looks like its written in a way that doesn't support async code? Usually libraries pass a callback function you can call when your async processing is done, like function(info, callback) {}, but webot does not appear to. Your best bet might be to assign courseName to the info object (info.courseName) you are given and notify your program to use courseName elsewhere.

Notes:

  • You should use somthing like mikeal/request to make requests outwards, as it's written specifically to do so.
Michael Tang
  • 4,686
  • 5
  • 25
  • 24