2017-09-18 2 views
0

대용량 csv 파일 (GB 단위)을 청크로로드하려고합니다. 다음 코드 :370 번째 반복 후 Async await in 루프가 중지됩니다.

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

reader.nextline는() while 루프가 실행되는 경우에도 라인 (370)의 작동이 중지 후. 그러나 내가 코드를 바깥에서 기다리면 코드가 제대로 작동하는 것 같습니다. 왜 이런 일이 일어나는가?

+0

함수는 모든 경우에 약속을 반환하지 않습니다. – Pointy

답변

2

문제의 원인이되는 콜백()과 콜백()이 섞여 있습니다.

특히, 모든 라인을 읽기 전에 호출되기 때문에 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 블록 밖으로 옮겨지기를 기다리고있을 때 코드가 왜 돌아 갔는지에 대해 혼란 스럽다. 또한 370 또는 그 이후에 try.nextLine()이 호출되지 않아도 while 루프가 계속 실행 중입니다 (잠시 시작하면서 로깅 확인). while 루프가 완료되지 않은 경우 루프 아래의 코드는 어떻게 실행됩니까? reader의 콜백과 같은 무언가를 여기 놓친 것입니까? nextline()은 아마도 비 차단일까요? – AshithR

+0

@AshithR 네, 그게 또 다른 것입니다 :'reader.nextLine()'이 전혀 차단되지 않습니다. 'if' 밖에서'await'을 움직이면, 읽혀지는 모든 행 (또한 정말로 충분하지는 않지만 충분히)에 도달 할 때까지 "차단"합니다 (실제로는 비동기입니다). 따라서 독자를 닫는 것은 모든 라인이 실제로 읽혀지는 지점에 훨씬 가깝게 일어날 것입니다. – robertklep