cómo iterar dos matrices una tras otra usando async forEach

Tengo dos matrices. Me gustaría iterar las matrices usando async.foreach. Pero cuando lo hago, solo se ejecuta la segunda matriz. Cómo ejecutar ambas. A continuación se muestra mi código:

var _sizesArray1 = [_2000px, _1400px] var _sizesArray2 = [_800px, _400px, _200px, _100px] async.forEachOf(_sizesArray1, function(value, key, callback) { async.waterfall([ function download(next){ //code }, function convert(response, next) { //code }, function process(response, next) { gm(response).command('convert') .resize(_sizesArray[key].width,_sizesArray[key].width) .gravity('Center') .extent(_sizesArray[key].width,_sizesArray[key].width) .quality('20') .toBuffer( 'JPG', function(err, buffer) { if (err) { next(err); } else { console.timeEnd( "processImage array1" ); next(null, buffer, key); } }); } }); async.forEachOf(_sizesArray2, function(value, key, callback) { async.waterfall([ function download1(next){ //code }, function convert2(response, next) { //code }, function process3(response, next) { //code } }); 

En mi código, solo se invoca array2. ¿Por qué no se ejecuta primero? ¿Hay algún error en mi código? ¿Puede alguien ayudar a resolver esto?

¿Qué tal esta sencilla técnica?

 var allSizes = _sizesArray1.concat(_sizesArray2); async.foreach(allSizes, function(value, key, next) { // do whatever you like with each item in the concatenated arrays // once you are done move to the next item next() }) 

Actualizado basado en comentarios

Versión 1, basada en devoluciones de llamada (bienvenido infierno de callback):

 function asyncIterate(array, onEach, onDone) { async.forEach(array, (val, index, onNext) => { onEach(val, key, function onDecoratedNext() { // tell the async.forEach it's ready for the next item onNext(); // but if it got to the end, // then mark the completion of the whole iteration if (index === array.length) { onDone(); } }); }); } 

e implementarlo como:

 function doAsyncStuffWithEachItem(val, index, cb) { // do async stuff with each item // make sure to mark the completion of the async operation cb(); } asyncIterate( _sizesArray1, doAsyncStuffWithEachItem, function onDone() { // once the 1st iteration finished, time to move to the 2nd array asyncIterate( _sizesArray2, doAsyncStuffWithEachItem, function onDone2() { // great we are done // What if we have _sizesArray3, 4, 5 ... ? // Well, we can continue to nest more callback here // but in that way we'll soon end up with callback hell // and that's a big NoNo } ) } ); 

Versión 2, basada en Promesas:

Para evitar el infierno de callback, por suerte podemos usar Promesas. Algo como esto debería hacerlo:

 const promisifiedAsyncIterate = (array, onEach) => new Promise((resolve) => { asyncIterate(array, onEach, resolve); }); 

y utilízalo como:

 promisifiedAsyncIterate(_sizeArray1, doAsyncStuffWithEachItem) .then(() => promisifiedAsyncIterate(_sizeArray2, doAsyncStuffWithEachItem)) .then(() => promisifiedAsyncIterate(_sizeArray3, doAsyncStuffWithEachItem)) .then(() => promisifiedAsyncIterate(_sizeArray4, doAsyncStuffWithEachItem)) 

Se podría abstraer y limpiar aún más, o incluso volverse completamente dynamic; digamos que tiene una gran variedad de arrays de tamaño que pasa a su función, pero creo que esto es suficiente por ahora :). Espero eso ayude.