我正在尝试节点的生成器函数,并在与事件侦听器回调一起使用时遇到问题。请检查我正在使用的代码
function* fileLineByLine(file){
var fs = require('fs'), readline = require('readline');
var rd = readline.createInterface({
input: fs.createReadStream(file),
output: process.stdout,
terminal: false
});
yield rd.on('line')
}
console.log(fileLineByLine('test.csv').next())
有人有想法吗?
答案 0 :(得分:1)
您无法退回每一行。节点readline是异步的。您可以使用thunk
获取值,但仍需要将回调传递给on
方法。
可选方法:
//start is a thunk creator
function start(cb){
var c = cb();
c.next(); //start up!
return function(message){
c.next(message);
};
}
rd.on('line', start(function(message){
var m = yield message;
console.log(m);
}));
答案 1 :(得分:0)
经过一夜的思考,这里有一个要点:Wrap readline's event based interface to co friendly
使用https://github.com/tj/co来驱动它。
TEST_CO-readline.js
var co = require('co'),
readline = require('./co-readline');
co(function* () {
var hosts = readline('/etc/hosts');
while (true) {
var line = yield hosts.read();
if (typeof(line) == 'string') {
console.log('result line: ' + line);
continue;
}
break;
}
}).then(function (value) {
console.error("value: " + (value || '').toString());
}).catch(function (e) {
console.error("catch: " + e.stack);
});
共readline.js
var co = require('co'),
assert = require('assert');
fs = require('fs'),
readline = require('readline');
module.exports = function (filename) {
var instance = {
lines: [],
closed: false,
errored: null,
callback: null,
read: function () {
return function (callback) {
assert(instance.callback === null);
if (instance.lines.length > 0) {
var line = instance.lines.shift()
callback(null, line);
if (instance.lines.length === 0) {
stream.resume();
}
return;
} else if (instance.closed) {
return callback(null, null);
} else if (instance.errored) {
return callback(instance.errored);
}
instance.callback = callback;
};
}
};
var stream = readline.createInterface({
input: fs.createReadStream(filename)
});
stream.on('line', function (line) {
instance.lines.push(line);
stream.pause();
if (instance.callback) {
var callback = instance.callback;
instance.callback = null;
callback(null, instance.lines.shift());
if (instance.lines.length == 0) {
stream.resume();
}
return;
}
}).on('close', function () {
instance.closed = true;
if (instance.callback && instance.lines.length == 0) {
var callback = instance.callback;
instance.callback = null;
return callback(null, null);
}
}).on('error', function (err) {
instance.errored = err;
if (instance.callback && instance.lines.length == 0) {
var callback = instance.callback;
instance.callback = null;
return callback(err);
}
});
return instance;
};