2016-04-14 3 views
0

Я пытаюсь извлекать изображения из файла CSV, выполнив следующие действия:createWriteStream «закрыть» событие не срабатывает

  1. Разбор/вытекание в большой CSV-файл с помощью csv-parse и fscreateReadStream метод
  2. Схват каждой строки для обработки с использованием stream-transform
  3. Извлечение изображения и других данных строки для обработки с использованием метода водопада async.
  4. Скачать и записать образ на сервер, используя request и fscreateWriteStream метод

По какой-то причине, после того, как получает данные по трубам в createWriteStream, есть какое-то событие, в котором async обратного вызова никогда не вызывается. Я использовал этот же код только с использованием request, без трубопроводов до createWriteStream, и он работает. Я также запускаю createWriteStream с событием drain, а затем как он работает? Кто-нибудь может мне это объяснить?

В приведенном ниже коде, request пытается трубы 14,970 изображений, но createWriteStreamclose или finish события только огонь 14,895 раз, с error стрельбы 0 раз. Может ли это быть проблемой истощения? Возможно ли превышение highWaterMark и отказ записи может быть обнаружен незамеченным?

Вот моя линия CSV получать код:

var first = true; 
var parser = parse(); 
var transformer = transform((line, complete) => { 
     if(!first) 
      extractData(line,complete) 
     else { 
      first = false; 
      complete(null); 
     } 
    }, 
    () => { 
     console.log('Done: parseFile'); 
    }); 
fs.createReadStream(this.upload.location).pipe(parser).pipe(transformer); 

extractData функция, которая не всегда делает необходимый async обратного вызова:

extractData(line,complete){ 
    var now = new Date(); 
    var image = { 
     createdAt: now, 
     updatedAt: now 
    }; 
    async.waterfall([ 
     next => { // Data Extraction 
      async.forEachOf(line, (data, i, complete) => { 
       if(i === 2) image.src = data; 
       if(i === 3) image.importSrc = data; 
       complete(null); 
      }, err => { 
       if(err) throw err; 
       next(null); 
      }); 
     }, 
     next => { // Download Image 
      var file = fs.createWriteStream('public/'+image.src); 
      var sendReq = request.get(image.importSrc); 
      sendReq.on('response', response => { 
       if (response.statusCode !== 200) { 
        this.upload.report.image.errors++; 
        return next(null); 
       } 
      }); 
      sendReq.on('error', err => { 
       this.upload.report.image.errors++; 
       next(null); 
      }); 
      sendReq.pipe(file); 
      file.on('finish',() => { 
       this.upload.report.image.inserts++; 
       file.close(next); // Close file and callback 
      }); 
      file.on('error', err => { 
       this.upload.report.image.errors++; 
       next(null); 
      }); 
     } 
    ], err => { 
     if(err) throw err; 
     complete(null); 
    }); 
} 

Как было предложено @mscdex, я также пытался выключение finish для его замены close подход.

ответ

0

file.close(next); не требуется, поскольку поток файлов автоматически закрывается по умолчанию. Вместо этого вы можете прослушать событие close, чтобы узнать, когда дескриптор файла для потока был закрыт. Таким образом, заменить весь обработчик события finish с:

file.on('close',() => { 
    this.upload.report.image.inserts++; 
    next(null); 
}); 
+0

Я дам ему идти, и пусть вы знаете, если он работал – user1828780

+0

я попытался выше, и это не сработало. Он пытается загрузить и запросить 14 970 изображений, но 'close' называется только 14 895 раз. Также 'error' вызывается 0 раз. – user1828780