带有 while 循环的 NodeJS 结束事件
NodeJS end event with while loop
我尝试使用 sax 迭代这个大 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
将记录 Done reading: 5
大约 43 次,如果我注释掉 while 循环,它只会控制台 Done reading: 5
once!,我做错了什么吗?是bug吗?
所以你想在需要继续数据管道的时候暂停一个可读流。这就是 shutdown
函数应该在管道范围之外的原因,您可以在 done
函数内将其作为 readable.pause
简单地暂停。
'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
}
}
当您从 saxStream.on('opentag') return 时,这意味着您已完成该标记的处理,但解析器会继续,直到完成整个 xml。
我尝试使用 sax 迭代这个大 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
将记录 Done reading: 5
大约 43 次,如果我注释掉 while 循环,它只会控制台 Done reading: 5
once!,我做错了什么吗?是bug吗?
所以你想在需要继续数据管道的时候暂停一个可读流。这就是 shutdown
函数应该在管道范围之外的原因,您可以在 done
函数内将其作为 readable.pause
简单地暂停。
'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
}
}
当您从 saxStream.on('opentag') return 时,这意味着您已完成该标记的处理,但解析器会继续,直到完成整个 xml。