2017-09-18 90 views
0

我试图在块中加载一个大的csv文件(GB的大小)。代码如下:第370次迭代后异步等待循环停止

lineReader.open(filename,async function(err, reader) { 
    if (err) throw err; 
    var dataArr=[]; 
    while (reader.hasNextLine()) { 
    reader.nextLine(function(err, line) { 
     if(err) throw err; 
     console.log(line); 
     dataArr.push(csv_parse(line,headers)); 
    }); 
    console.log(dataArr.length); 
    if(dataArr.length == 3000){ 
     console.log(JSON.stringify(dataArr)); 
     await timeout(6000); 
     console.log("timeout"); 
     dataArr = []; 
    } 
    } 
    reader.close(function(err) { 
     if (err) throw err; 
    }); 
}); 

即使执行while循环,reader.nextline()在370行后停止工作。然而,当我移动等待代码似乎工作正常。这是为什么发生。

+0

您的功能并非在所有情况下都返回的承诺。 – Pointy

回答

2

您在混合承诺(async/await)和回调(reader.nextLine()),这会导致您的问题。

具体而言,您打电话reader.close()太早,因为它在所有行被读取之前被调用;可以读取的370行可能适合从文件读取之前从文件中读取的缓冲区。

一个解决办法是也使读出下一行承诺为基础的,比如像这样:

const getNextLine = async reader => { 
    return new Promise((resolve, reject) => { 
    reader.nextLine(function(err, line) { 
     if (err) return reject(err); 
     resolve(line); 
    }); 
    }); 
} 

lineReader.open(filename, async function(err, reader) { 
    if (err) throw err; 
    var dataArr = []; 
    while (reader.hasNextLine()) { 
    let line = await getNextLine(reader); 
    dataArr.push(csv_parse(line, headers)); 
    console.log(dataArr.length); 
    if (dataArr.length == 3000) { 
     console.log(JSON.stringify(dataArr)); 
     await timeout(6000); 
     console.log("timeout"); 
     dataArr = []; 
    } 
    } 
    reader.close(function(err) { 
    if (err) throw err; 
    }); 
}); 
+0

谢谢,这很好。但是我仍然对为什么代码在等待timeout()被移出if区块时运行感到困惑。同样,即使reader.nextLine()停止在370尝试之后被调用,while循环仍在运行(通过在开始时记录来检查)。循环下面的代码在未完成时如何执行。我在这里错过了什么,或许reader.nextline()的回调可能是非阻塞的? – AshithR

+0

@AshithR是的,这是另一回事:'reader.nextLine()'根本就没有阻塞。当你将'await'移到'if'之外时,它将“阻塞”(不是真的,它是异步的),直到达到超时为止,读取的每一行(也不是真的,但足够接近)。因此关闭阅读器将会更接近所有行被实际阅读的地方。 – robertklep