带有while循环的NodeJS结束事件

我尝试使用萨克斯迭代这个大的XML文件,这里是代码:

'use strict'; const fs = require('fs'); const sax = require('sax'); let rowsAdded = 0; let rows = []; let options = { encoding: 'utf8', mode: 0o444 }; let strict = true, feedFile = 'Comments.xml', saxStream = sax.createStream(strict); saxStream.on('opentag', node => { if(rowsAdded === 5) { return saxStream.end(); } // I only need nodes named 'row' if(node.name === 'row') { rowsAdded++; // If the name is 'row' and `attribute` prop exists, push it. if(node.attributes) rows.push(node.attributes); } }) .on('error', () => { }) .on('end', () => { console.log('Done reading:', rowsAdded); // If you remove this while loop the above console will called only once while(rowsAdded--) { } }); fs.createReadStream(feedFile, options).pipe(saxStream); 

console.log会loggingDone reading: 5大约43次,如果我注释掉while循环,它只会执行Done reading: 5 次! ,我做错了什么?这是一个错误吗?

当你从saxStream.on('opentag')返回时,意味着你已经完成了这个标签的工作,但是parsing器一直持续到完成整个xml。

所以,当你需要继续数据pipe道的时候,你想暂停一个Readablestream。 这就是为什么shutdown函数应该超出了pipe道的范围,在那里你可以简单地将它暂停为readable.pause内部done函数。

 'use strict'; const fs = require('fs'); const sax = require('sax'); let rowsAdded = 0; let rows = []; let options = { encoding: 'utf8', mode: 0o444 }; let strict = true, feedFile = 'Comments.xml', saxStream = sax.createStream(strict); saxStream.on('opentag', node => { // I only need nodes named 'row' if(node.name === 'row' && rowsAdded < 5) { rowsAdded++; // If the name is 'row' and `attribute` prop exists, push it. if(node.attributes) rows.push(node.attributes); } if(rowsAdded === 5) done(); }) .on('error', () => { }) .on('end', () => { console.log('Done reading:', rowsAdded); }); var readable = fs.createReadStream(feedFile, options) readable.pipe(saxStream); function done(){ // this should stop reading part. readable.pause(); while(rowsAdded--) { // do you processing here } }