2016-02-28 39 views
1

我嘗試通過解析器傳輸CSV文件,刪除給定ID的行,將新數組傳遞給字符串,最後將結果輸出爲新的CSV。Node.js流API的意外行爲

問題是新數組未正確返回。我的意思是,我設法刪除行但不返回新的CSV。

這裏是CSV file

這裏是代碼:

'use strict'; 


const Fs = require('fs'); 
const Csv = require('csv'); 


let input = 'data_stack.csv'; 
let output = 'data_output.csv'; 


let readStream = Fs.createReadStream(input); 
let writeStream = Fs.createWriteStream(output); 

let opt = {delimiter: ',', quote: '"', escape: '"', relax: true, skip_empty_lines: true}; 

function deleteRow (id) { 

    return Csv.parse(opt, (err, data) => { 
     if (err) throw err; 

     let delId = []; 
     // The row corresponding to the id is pushed to an array to console.log it. The other rows are returned 
     let newData = data.filter(line => { 
      if (line[0] === id) { 
       delId.push(line); 
      } 
      else { 
       return line; 
      } 
     }); 

     if (delId !== 0) { 
      console.log("Deleted line\n"); 
      console.log(delId); 
     } 

     // Testing if the row was deleted 
     let result = []; 
     // If the row is not deleted, push it into the result array 
     newData.forEach(line => { 
      if (line[0] === id) { 
       result.push(line); 
      } 
     }); 
     // "Not found !" is console logged. The row has been deleted 
     if (result.length !== 0) { 
      console.log(result); 
     } 
     else { 
      console.log("Not found !"); 
     } 

     return newData; 
    }); 
} 

readStream.pipe(deleteRow('566150121ae803f53751c3f2')) 

此代碼工作 但如果我選擇則newData陣列返回管它的一個stringifier輸出結果到CSV文件,我得到2種意外行爲:

  1. 的delId陣列現在是空的,我不知道爲什麼
  2. 創建
  3. 輸出文件,但是那是以前刪除的行仍然存在輸出文件

下面是代碼:

'use strict'; 


const Fs = require('fs'); 
const Csv = require('csv'); 


let input = 'data_stack.csv'; 
let output = 'data_output.csv'; 


let readStream = Fs.createReadStream(input); 
let writeStream = Fs.createWriteStream(output); 

let opt = {delimiter: ',', quote: '"', escape: '"', relax: true, skip_empty_lines: true}; 

function deleteRow (id) { 

    return Csv.parse(opt, (err, data) => { 
     if (err) throw err; 

     let delId = []; 
     // The row corresponding to the id is pushed to an array to console.log it. The other rows are returned 
     let newData = data.filter(line => { 
      if (line[0] === id) { 
       delId.push(line); 
      } 
      else { 
       return line; 
      } 
     }); 

     if (delId !== 0) { 
      console.log("Deleted line\n"); 
      console.log(delId); 
     } 

     // Testing if the row was deleted 
     let result = []; 
     // If the row is not deleted, push it into the result array 
     newData.forEach(line => { 
      if (line[0] === id) { 
       result.push(line); 
      } 
     }); 
     // "Not found !" is console logged. The row has been deleted 
     if (result.length !== 0) { 
      console.log(result); 
     } 
     else { 
      console.log("Not found !"); 
     } 

     return newData; 
    }); 
} 

let stringifier = Csv.stringify({quoted: true}); 

readStream.pipe(deleteRow('566150121ae803f53751c3f2')).pipe(stringifier).pipe(writeStream); 

我真的不知道如何從管道結果deleteRow函數會影響其行爲。

有沒有建議嗎?

回答

0

csv.parse具有2 APIs

  1. 回調基於(緩衝液)和;
  2. 基於流。

如果傳遞的回調函數,因爲你是在你的例子做,你訂閱回調API,這意味着其整體全解析的數據通過data參數是提供給您。

但是,該回調是流「匯」,這意味着對數據的任何修改都不會影響到您的writeStream

你需要調整代碼要麼使用回調API,像這樣:

function deleteRow(readStream, id, done) { 
    readStream.pipe(Csv.parse(opt, (err, data) => { 
    if (err) return done(err); 

    // Wrire new data to file 
    Csv.stringify(data.filter(line => line[0] !== id)) 
     .pipe(writeStream) 
     .on('end', done); 
    })); 
} 

deleteRow(readStream, '5660d7e11ae803f53751aeb0', function (err) { 
    console.log('done!'); 
}); 

或者,利用流API是這樣的:

+0

@Ixe,你忘了結束您的帖子。你可以添加它,所以我可以比較,以確保我完全理解 – Synleb