Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript callback vs return

I have a JavaScript (Node) function to grab the content of a web page and handle it with a callback:

'using strict';
var http = require('http');

function download(url, callback) {
  http.get(url, function(res) {
    var content = '';
    res.on('data', function (chunk) {
      content += chunk;
    });
    res.on('end', function() {
      callback(content);
    });
  }).on('error', function() {
    callback(null);
  });
}

What I don't understand is why I can't simply return the result on 'end'. Clearly, when the 'end' event is emitted, the 'content' variable contains a string with the content of a web page, otherwise it couldn't be submitted to the callback function, so why can't I just return it like this:

function download2(url) {
  http.get(url, function(res) {
    var content = '';
    res.on('data', function(chunk) {
      content += chunk;
    });
    res.on('end', function() {
      return content;
    });
  }).on('error', function() {
    return null;
  });
}

download2 always returns undefined. Why?

like image 671
Suugaku Avatar asked Apr 24 '14 00:04

Suugaku


1 Answers

These are asynchronous functions. They have already long since completed before the callback functions are called. Thus the desired return result is not known when either of your download functions returns. For data passed to asynchronous callbacks, the ONLY place you can do something with that data is from the callback itself. You can put your code to handle that data in the callback or you can call some other function from within the callback and pass the data to it.

This is asynchronous programming and you really have to get used to it in node because it's used there a lot. It is significantly different than synchronous programming in that you can't call a function that starts an asynchronous operation and expect the parent function to get the result and return it. The result of the asynchronous operation won't be known until sometime later, long after the parent function has already returned.

Thus, the way you've structured it in your first download() function is the usual way of handling this.

like image 59
jfriend00 Avatar answered Sep 21 '22 11:09

jfriend00