¿Cuál es la diferencia entre async.waterfall y async.series?

Respuestas:

168

Parece que async.waterfallpermite que cada función pase sus resultados a la siguiente función, mientras que async.seriespasa todos los resultados a la devolución de llamada final. En un nivel superior, async.waterfallsería para una canalización de datos ("dado 2, multiplíquelo por 3, sume 2 y divida por 17"), mientras async.seriesque sería para tareas discretas que deben realizarse en orden, pero que por lo demás están separadas.

Twisol
fuente
¿Es posible que alguna de estas dos funciones devuelva un valor? He leído que es posible, pero no encuentro información relevante en ninguna parte de la documentación.
Anderson Green
1
@AndersonGreen: No. Mirando la fuente de la biblioteca, ni waterfallni seriesdevuelve un valor. Se espera que sea cual sea el resultado, se utilizará en el parámetro de devolución de llamada opcional.
Twisol
La respuesta anterior puede ser correcta hasta 2012, pero la correcta es la misma que la siguiente, que es: series () ya que se llama que TODOS los resultados como una serie se pasan a la devolución de llamada final, y la cascada es el ÚLTIMO resultado que se pasa a la devolución de llamada final. Ver desarrollador de Mozilla
Jeb50
53

Ambas funciones pasan el valor de retorno, de cada función a la siguiente, luego, cuando termine, llamará a la devolución de llamada principal, pasando su error, si ocurre un error.

La diferencia es que async.series(), una vez finalizada la serie, se pasarán todos los resultados al callback principal. async.waterfall()pasará a la devolución de llamada principal solo el resultado de la última función llamada.


fuente
1
Esta debería ser la respuesta ;-)
Stuart Allen
@Mario "¿Ambas funciones pasan la devolución de llamada de la función anterior" O "Ambas funciones pasan el resultado de la función anterior"?
user1451111
@ user1451111, Resultado, lol ... Estoy seguro de que me había escrito que la primera vez, sin embargo ...
26

async.waterfall()está tratando con un action that relies on the previous outcome.

async.series() se trata de una acción que quiere see all the result at the end

Wayne Chiu
fuente
1
Imágenes increíblemente creadas. ¿Los creaste tú mismo o los compraste en otro lugar?
user1451111
debe poner las imágenes en la respuesta, la gente probablemente las extrañará o / w
Alexander Mills
1

Considero que async.waterfall es dañino, porque es difícil de refactorizar una vez escrito y también es propenso a errores, ya que si proporciona más argumentos, otras funciones cambian mucho la firma.

Recomiendo encarecidamente async.autoInjectcomo una gran alternativa, async.waterfall. https://caolan.github.io/async/autoInject.js.html

Si elige usar async.waterfall, le recomiendo almacenar todo en un objeto, para que sus funciones no tengan que cambiar la longitud / firmas, así:

advertencia: este es un mal patrón

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

no lo hagas de la forma anterior. Este es un patrón mucho mejor para usar:

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

de esa manera no se arrancará los pelos tratando de asegurarse de que los argumentos de la función tengan la longitud correcta. La primera función solo acepta un argumento de devolución de llamada. Todos los restantes deben aceptar dos argumentos: un valor y una devolución de llamada. ¡Apégate al patrón y permanecerás cuerdo!

Alexander Mills
fuente