Страницы

воскресенье, 6 июля 2014 г.

Async vs. Callback Hell. Update

В предыдущем посте я показал пару приемов применения модуля async на простом примере. Сегодня этот пост мне показался незавершенным, тема не до конца раскрытой, код недописанным, Callback Hell недолеченным, в общем спешу поделиться более убедительным по моему мнению решением рассмотренного вопроса.


Приведенный ниже код говорит сам за себя - теперь все так разложено по полочкам, что по-моему не разобраться что к чему крайне затруднительно. Комменты в помощь:
var async = require('async');

getData(function(data) { // получаем данные, асинхронно
  async.waterfall([
    async.apply(step1, data), // шаг №1 - сложение и умножение
    async.apply(step2, data), // шаг №2 - вычитание
  ], function(err) {
    if (err) console.log('err:', err.message);
    console.log('data:', data);
  });  
});

function step1(data, cb) {
  async.each(data, function(obj, next) { // асинхронно для каждого полученного объекта
    async.parallel([ // одновременно выполняем сложение и умножение
      async.apply(add, obj), 
      async.apply(multiply, obj)
    ], next);    
  }, cb);
}

function step2(data, cb) {
  async.each(data, function(obj, next) { // асинхронно для каждого полученного объекта
    subtract(obj, next); // выполняем вычитание
  }, cb);
}

function getData(cb) {
  setTimeout(function() {
    console.log('Getting data...');
    return cb([{a: 3}, {a: 5}]);
  }, 1000);
}

function add(obj, cb) {
  setTimeout(function() {
    // if (obj.a === 3) return cb(new Error('Achtung!'));
    obj.b = obj.a + obj.a;
    console.log('%d plus %d = %d', obj.a, obj.a, obj.b);
    cb();    
  }, 1000);
}

function multiply(obj, cb) {
  setTimeout(function() {    
    obj.c = obj.a * obj.a;
    console.log('%d times %d = %d', obj.a, obj.a, obj.c);
    cb();
  }, 1000);
}

function subtract(obj, cb) {
  setTimeout(function() {    
    obj.d = obj.c - obj.b;
    console.log('%d minus %d = %d', obj.c, obj.b, obj.d);
    cb();
  }, 1000);
}

Результат:

Все, теперь точно тру, не правда ли?