0

I was trying node's generator functions and getting issue when used with event listener callback. Please check the code I am using

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

Anybody have an idea?

AntouanK
  • 4,880
  • 1
  • 21
  • 26
Amal
  • 545
  • 6
  • 19
  • 1
    So? `rd.on('line')` is not returning a value, is it? (or does it return a promise?) What is your problem? What are you trying to do at all, logging the first line? – Bergi Apr 23 '15 at 15:53
  • 1
    Yeah what are you expecting to happen here? You're not passing a callback to `rd.on('line')`. I'm not super familiar with generator functions yet but that doesn't seem right to me. – CatDadCode Apr 23 '15 at 16:15
  • I would like to return each line. – Amal Apr 23 '15 at 16:32
  • Essentially a duplicate of [ES6 generators: transforming callbacks to iterators](https://stackoverflow.com/questions/29699109/es6-generators-transforming-callbacks-to-iterators) – Dan Dascalescu Jun 14 '19 at 20:51

2 Answers2

1

You can't return each line. node readline is asynchronous. You could get the value from using a thunk, but you still have to pass a callback to the on method.

An optional way to do it:

//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);
}));
Quentin Engles
  • 2,744
  • 1
  • 20
  • 33
-1

With one night thought, here is the gist: Wrap readline's event based interface to co friendly

It use https://github.com/tj/co to driven it.

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;
};
tangxinfa
  • 1,410
  • 13
  • 12