Node.JS - Fundamentals of Asynchronous Programming, Part 1

    Now, after the release of the stable version of Node.JS 0.2.0 , I decided to start a series of programming articles using it.

    The basic concept of Node.JS is that by default, any I / O operations are implemented as asynchronous, after the operation is completed, a callback function will be called, the first parameter of which will be an error or null.

    Hide Asynchronous Nesting


    Suppose we need to create a directory, including all of its parents. And only if it was possible to create it, start writing in this directory.

    In order to hide the complexity of working with asynchronous operations, we take out the work of creating a directory in a separate asynchronous method:

    var path     = require('path');
    var fs      = require('fs');

    var mkdir_p = function(pth, callback)
    {
        fs.stat(pth, function(err, stat)
        {
            if (!err && stat)
            {
                callback(null);
                return;
            }
            mkdir_p(path.dirname(pth), function(err)
            {
                if (err)
                {
                    callback(err);
                    return;
                }
                fs.mkdir(pth, 0755, callback);
            });
        });
    };

    * This source code was highlighted with Source Code Highlighter.

    The function first checks for the presence of the directory, and if it exists, calls the callback function without error. If the directory is absent, mkdir_p is called for the parent directory, and then the required directory is created.

    As you can see, it was possible to successfully implement recursion and pass error information to the callback function as standard for Node.JS.

    We use, for example, like this:

      mkdir_p(path.dirname(outPath), function(err)
      {
        if (err)
        {
          response.writeHead(500, {'Content-Type': 'text/plain'});
          response.end('Cannot create directory');
          return;
        }
        getFile(url, inPath, function(err)
        {
          if (err)
          {
            response.writeHead(500, {'Content-Type': 'text/plain'});
            response.end('Cannot read file');
            return;
          }
          transcode(inPath, outPath, function(err)
          {
            if (err)
            {
              response.writeHead(500, {'Content-Type': 'text/plain'});
              response.end('Cannot transcode file');
              return;
            }
            sendRemoveFile(outPath, response, function(err)
            {
              if (err)
              {
                console.log('Cannot send file');
                return;
              }
            });
          });
        });
      });

    * This source code was highlighted with Source Code Highlighter.


    In the next article I will tell you about working with external processes.


    Also popular now: