Async queue, filestream end, как узнать, когда оба завершены

У меня возникает небольшая проблема при использовании asyncqueue с файловым потоком

  • У меня есть сценарий, в котором завершится мой фид
  • Я установил fileRead в true
  • однако очередь будет пустой и уже вызвала дренаж
  • это приводит к тому, что мое "сделано" никогда не будет называться

Каков правильный способ сказать "закончить очередь" после того, как мой поток "end" и очередь пуста?

var fs = require('fs')
    , util = require('util')
    , stream = require('stream')
    , es = require('event-stream');

var async = require('async');

var fileRead = false;
var lineNr = 0;

var q = async.queue(function(task, callback) {
    task(function(err, lineData){
        responseLines.push(lineData);
        callback();
      });
  }, 5);

var q.drain = function() {
  if(fileRead){
    done(null, responseLines);
  }
}

var s = fs.createReadStream('very-large-file.csv')
    .pipe(es.split())
    .pipe(es.mapSync(function(line){
        s.pause();
        q.push(async.apply(insertIntoDb, line))
        s.resume();
    })
    .on('error', function(err){
       done(err);
    })
    .on('end', function(){
      fileRead = true;
    })
);

Ответ 1

Во-первых, я не уверен, насколько ваш фрагмент является псевдокодом, но var q.drain = ... недействителен javascript и должен быть ошибкой. Это должно быть просто q.drain =, поскольку вы определяете свойство существующего объекта, не объявляя новую переменную. Это может быть причиной того, что ваша функция стока не срабатывает, если она не является псевдокодом.

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

.on('end', function(){
  if(!q.length){
    callDone();
  }
  else {
    q.drain = callDone;
  }
});

function callDone(){
  done(null, responseLines);
}

Это эффективно говорит "если обработанный вызов очереди выполнен, если нет, вызовите его, когда он есть!" Я уверен, что есть много способов убрать ваш код, но, надеюсь, это обеспечивает решение вашей конкретной проблемы.