Sunday, July 14, 2013

Discovering JavaScript Closures

One of the biggest issues I have with JavaScript are callback functions which cannot access data from their parents scope. I tried OOP to get around this problem, yet the lack of a reliable $this variable voids those efforts pretty much.

Right now I'm working on a piece of middleware which should download a file from a CouchDB server, send it to a service providers API and obviously update the source document with the result.

Sounds easy, but if the callbacks don't know about the CouchDB document any longer this simple task quickly becomes a nightmare.

And so it happened that I've discovered this article about JS closures. Not entirely sure how it works under the hood but it sure solved my problem. The final code looks a bit like this:

function change_processor(change, param) {

  return {

    download: function() {

      for (var filename in change.doc._attachments) {                                               
        http.get({
          url: param.dbhost,
          port: param.dbport,
          path: '/' + param.dbname + '/' + change.doc._id + '/' + filename
        }, function(res) {
          var data = [];
          var dataLen = 0;
          res.on('data', function(chunk) {
            data.push(chunk);
            dataLen += chunk.length;
          }).on('end', function() {
            var buf = new Buffer(dataLen);
            for (var i=0, len = data.length, pos = 0; i < len; i++) {
              data[i].copy(buf, pos);
              pos += data[i].length;
            }
            console.log(buf.toString('ascii'));
          });
        });
      }
    }
  }
}

module.exports = change_processor;

The cool thing about this closure is that variables like `change` are available throughout the entire construct, including the callbacks of http.get. It's incredible.

No comments :

Post a Comment