2017-02-09 58 views
10

我使用async.queue与FILESTREAM时有轻微问题异步队列,文件流到底怎么知道什么时候都完成

  1. 我遇到的情况,我的FILESTREAM将完成
  2. 我设置FILEREAD到真正
  3. 但是队列将是空的,已经被称为漏
  4. 这进而导致我的“做”永远不会被称为

在我的文件流是“结束”并且队列为空之后,说“结束队列”的正确方法是什么?

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; 
 
    }) 
 
);

或是否有更好的使用异步的,这将允许我这样做?通过线 异步过程符合提前退出,如果其中一条线路有错误

+0

您可以在将'fileRead'设置为true后立即添加另一个任务。我认为你的问题是你调用每个队列项目的'task'函数被调用并在你的流上调用'end'事件之前完成。 – forrestmid

回答

1

首先的能力,我不知道有多少你的片断是伪代码,但var q.drain = ...是不是有效的JavaScript,应该错误。它应该是q.drain =,因为您在现有对象上定义属性而不声明新变量。这可能是为什么你的排水功能不是伪造代码的情况下不会触发。

有几种方法可以实现我认为你正在尝试做的事情。一种方法是检查结束处理程序中的队列长度,如果还有项目需要处理,则设置排水功能。

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

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

这实际上是说,“如果队列的被处理调用来完成,如果没有,打电话的时候就做了!”我确信有很多方法可以清理代码,但希望这可以为您的特定问题提供解决方案。

相关问题