В чем разница между async.waterfall и async.series - PullRequest
109 голосов
/ 13 февраля 2012

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

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

Ответы [ 4 ]

162 голосов
/ 13 февраля 2012

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

51 голосов
/ 08 января 2013

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

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

27 голосов
/ 31 августа 2016

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

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

1 голос
/ 04 февраля 2019

Я считаю 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) => {
     // ...
  }
])

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

...