Async: Версия async.series, где каждая задача получает результаты всех предыдущих задач

Созданный на 16 нояб. 2015  ·  5Комментарии  ·  Источник: caolan/async

Я часто сталкиваюсь с ситуацией, когда задаче async.series требуются результаты нескольких предыдущих задач. async.waterfall недостаточно, поскольку он предоставляет только результат последней предыдущей задачи. async, auto слишком подробен и предоставляет дополнительное ненужное объявление зависимостей.

Пригодится новая функция (или улучшение async.series). Каждая задача получит объект результата, содержащий результаты всех предыдущих задач.

Возможные названия: накапливать, ряды, накапливать

Пример:

async.accumulate({
    one: function(callback){
        setTimeout(function(){
            callback(null, 1);
        }, 200);
    },
    two: function(callback, results){
        // results: {one: 1}
        setTimeout(function(){
            callback(null, 2);
        }, 100);
    },
    three: function(callback, results){
         // results: {one: 1, two: 2}
        setTimeout(function(){
            callback(null, results.one + results.two);
        }, 100);
    }
},
function(err, results) {
    // results is now equal to: {one: 1, two: 2, three: 3}
});
feature question

Все 5 Комментарий

Вы проверяли async.auto ? Он делает нечто очень похожее на то, что вы описываете.

Как я уже упоминал, в сценарии простой серии async.auto слишком подробен. Пользователь должен объявить, что каждый шаг зависит от предыдущего, что приводит к этим уродливым массивам и дублированию имен шагов.

async.auto({
    one: function(callback){
        setTimeout(function(){
            callback(null, 1);
        }, 200);
    },
    two: ["one", function(callback, results){
        setTimeout(function(){
            callback(null, 2);
        }, 100);
    }],
    three: ["two", function(callback, results){
        setTimeout(function(){
            callback(null, results.one + results.two);
        }, 100);
    }
   ]
},
function(err, results) {
    // results is now equal to: {one: 1, two: 2, three: 3}
});

Мы собираемся внести некоторые улучшения в auto в следующем основном выпуске - всегда иметь обратный вызов последним, а также добавить autoInject (# 608), который определяет зависимости по именам параметров.

Мне не нравится это предложение, потому что оно зависит от порядка ключей объекта - что не гарантируется в средах JS (и гарантируется только в Node для небольших объектов). С массивами это возможно, но это слишком похоже на async.waterfall . Я не уверен, что нам нужно что-то среднее между auto и waterfall , особенно если мы добавляем autoInject .

Способ добиться того, чего вы хотите:

function seriesAccumulate(tasks, done) {
  async.reduce(tasks, [], function (results, task, next) {
    task(results, function (err, result) {
      results.push(result);
      next(err, result);
    });
  }, done);
}

Я бы не рекомендовал использовать объект для последовательной итерации.

Закрытие этого. Я не думаю, что нам нужен другой метод между series и waterfall в стиле.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги