Summing CSV files row by row using Node.js events
If you want to check whether every item in an array passes a test, you should use .every for that, not .reduce. Eg

data.reduce((acc, el) =&gt; acc &amp;&amp; el.length &gt; 0, true)


can be switched with

data.every(arr =&gt; arr.length)


and

data.reduce((acc, el) =&gt; acc &amp;&amp; el[0] === null, true)


can be switched with

data.every(arr =&gt; arr[0] === null)


Also, when you want to transform one array into another, .map is the right method, not .reduce. Or, when you just want to copy an array exactly, use .slice() or spread it. Change

data.reduce((acc, el) =&gt; {
  acc.push(el.shift());
  return acc;
}, [])


to

[...data]



On a broader note, I would consider the logic to be a lot easier to follow if it was separated into two parts: one part to read the files and deal with the asynchronicity, and another part to (synchronously) combine into a single array. I think mixing the two and using eventEmitter makes things more difficult to understand than they need to be.

A somewhat minor issue is that you're requiring all rows of a particular index to be kept in memory until they've all been parsed. In the case that you're dealing with a large number of files, or the rows are large, it would be better to combine them as soon as possible, as they come in, so that the only persistent data structure is the output array of arrays (rather than an array of arrays for each separate .csv).

When any row is parsed, you can call a function that combines it with the results array. You can also map each parseStream to a Promise that resolves once its end event fires, and use Promise.all to log the final results array once all parsers are completed:

const result = [];
const combineRow = (row, rowIndex) =&gt; {
  const targetRow = result[rowIndex];
  if (!targetRow) {
    result[rowIndex] = row;
    return;
  }
  row.forEach((cell, cellIndex) =&gt; {
    targetRow[cellIndex] = (targetRow[cellIndex] || 0) + cell;
  });
}
const getRows = parser =&gt; new Promise((resolve, reject) =&gt; {
  let rowIndex = 0;
  parser.on('readable', () =&gt; {
    const row = parser.read();
    if (row) {
      combineRow(row.map(Number), rowIndex);
      rowIndex++;
    }
  });
  parser.on('end', resolve);
});

Promise.all(parsers.map(getRows))
  .then(() =&gt; {
    console.log(result);
  });


https://repl.it/repls/EnchantedElaborateFiber