【问题标题】:Node.js generator function on event listener callbacks [duplicate]事件侦听器回调上的 Node.js 生成器函数 [重复]
【发布时间】:2015-07-01 22:21:49
【问题描述】:

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

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

有人有想法吗?

【问题讨论】:

  • 所以? rd.on('line') 没有返回值,是吗? (或者它是否返回一个承诺?)你的问题是什么?你到底想做什么,记录第一行?
  • 是的,您希望在这里发生什么?您没有将回调传递给rd.on('line')。我对生成器函数还不是很熟悉,但这对我来说似乎不太合适。
  • 我想退回每一行。

标签: javascript node.js generator


【解决方案1】:

想了一晚上,这里是要点: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);
});

co-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;
};

【讨论】:

    【解决方案2】:

    您不能返回每一行。节点读取线是异步的。您可以使用 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);
    }));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-02
      • 2018-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多