Node.js生成器函数对事件侦听器回调

时间:2015-04-23 15:48:04

标签: javascript node.js generator

我正在尝试节点的生成器函数,并在与事件侦听器回调一起使用时遇到问题。请检查我正在使用的代码

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())

有人有想法吗?

2 个答案:

答案 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;
};