Pull to refresh

Node.JS — Основы асинхронного программирования, часть 1

Reading time 3 min
Views 6.4K
Сейчас, после выхода стабильной версии Node.JS 0.2.0, я решил начать цикл статей по программированию с его использованием.

Основная концепция Node.JS — любые операции ввода-вывода по умолчанию реализованы как асинхронные, после выполнения операции будет вызвана функция обратного вызова, первым параметром которой будет являться ошибка или null.

Скрываем асинхронную вложенность


Предположим, нам нужно создать каталог, включая всех его родителей. И только в случае, если его удалось создать, начать писать в этот каталог.

Для того, чтобы скрыть сложность работы с асинхронными операциями, вынесем работу по созданию каталога в отдельный асинхронный метод:

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.

Функция сперва проверяет наличие каталога, и в случае его наличия вызывает функцию обратного вызова без ошибки. В случае, если каталог отсутствует, вызывается mkdir_p для каталога-родителя, и затем создаётся искомый каталог.

Как видите, удалось удачно реализовать рекурсию, и стандартным для Node.JS передать информацию об ошибках в функцию обратного вызова.

Используем, например, так:

  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.


В следующей статье расскажу вам о работе с внешними процессами.

Tags:
Hubs:
-2
Comments 17
Comments Comments 17

Articles