В чем разница между async.waterfall и async.series

Асинхронный модуль nodejs: https://github.com/caolan/async предоставляет два похожих метода: async.waterfall и async.series.

В чем разница между ними?

Ответ 1

Похоже, что async.waterfall позволяет каждой функции передавать свои результаты следующей функции, а async.series передает все результаты в окончательный обратный вызов. На более высоком уровне async.waterfall будет для конвейера данных ( "учитывая 2, умножьте его на 3, добавьте 2 и разделите на 17" ), а async.series будет для дискретных задач, которые должны выполняться по порядку, но в остальном раздельны.

Ответ 2

Обе функции передают возвращаемое значение, каждой функции в следующую, а затем, когда это будет сделано, вызовет основной обратный вызов, передав его ошибку, если произойдет ошибка.

Разница в том, что async.series(), как только серия закончится, передаст все результаты в основной обратный вызов. async.waterfall() перейдет к основному обратному вызову только к результату последней вызванной функции.

Ответ 3

async.waterfall() имеет дело с action that relies on the previous outcome.

async.series() имеет дело с тем, что хочет see all the result at the end

Ответ 4

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

Я настоятельно рекомендую async.autoInject как отличную альтернативу async.waterfall. https://caolan.github.io/async/autoInject.js.html

Если вы решите использовать async.waterfall, я рекомендую хранить все в одном объекте, чтобы вашим функциям не приходилось изменять длину/подписи, например:

предупреждение: это плохая картина

async.waterfall([
  cb => {
    cb(null, "one", "two");
  },
  (one, two, cb) => {
    cb(null, 1, 2, 3, 4);
  },
  (one,two,three,four,cb) => {
     // ...
  }
])

не делай этого вышеописанным способом. Это гораздо лучший шаблон для использования:

async.waterfall([
  cb => {
    cb(null, {one:"one", two:"two"});
  },
  (v, cb) => {
    cb(null, [1, 2, 3, 4]);
  },
  (v,cb) => {
     // ...
  }
])

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