节点readline'line'事件未触发

时间:2017-05-27 22:09:02

标签: javascript node.js events promise readline

我正在创建一个程序,它找到2个单词文件的常用单词,然后创建一个只包含常用单词的新文件。 我正在使用readline模块读取第一个单词文件的每个单词,然后将该单词存储在Trie中。在完成之后,我正在尝试读取其他单词文件中的单词,如果它是trie,我正在写入文件。

我正在使用promises来确保事件按顺序发生,但是第二次没有触发'line'事件。

'use strict'
const readLine = require('readline');
const fs = require('fs');

const wordList = require('./Trie.js');

function createTrie(reader, trie) {
  return new Promise((resolve, reject) => {
    if(typeof reader === 'undefined' || reader === null)
      reject('Failed')

    reader.on('line', line => trie.add(line))
    reader.on('close', () => {
      console.log('done')
      resolve(trie)
    })
  })
}

function findCommon(reader, trie) {
  return new Promise((resolve, reject) => {
    if(typeof reader === 'undefined' || reader === null) {
      console.log('failed')
      reject('Failed')
    }

    let commonWords = ''

    console.log('we are here')

    reader.on('line', (line) => {
      console.log(line) // This does not output
      if(line.length > 2 && trie.search(line)) {
        let word = line + '\n'
        commonWords += word
      }
    })
    reader.on('close', () => {
      fs.writeFile('wordlist.txt', commonWords, (err) => {
        if(err) {
          console.log(err)
          reject('error')
        }
        console.log('written')
        resolve('Success')
      })
    })
  })
}

let reader_1 = readLine.createInterface({
  input: fs.createReadStream('words/enable2k.txt')
})
let reader_2 = readLine.createInterface({
  input: fs.createReadStream('words/engmix.txt')
})

createTrie(reader_1, wordList)
  .then((trie) => findCommon(reader_2, trie))
  .then((data) => console.log(data))

上面的代码给出了以下输出

done
we are here

未触发'line'事件。好像我没有正确使用readline,但我不确定。

感谢任何帮助!

2 个答案:

答案 0 :(得分:0)

显然输入流已关闭。 我在findCommon函数中记录了读者,这是结果(只是相关部分)

ReadStream {
     _readableState: 
      ReadableState {
        objectMode: false,
        highWaterMark: 65536,
        buffer: [Object],
        length: 0,
        pipes: null,
        pipesCount: 0,
        flowing: false,
        ended: true,
        endEmitted: true,
        reading: false,
        sync: false,
        needReadable: false,
        emittedReadable: false,
        readableListening: false,
        resumeScheduled: false,
        defaultEncoding: 'utf8',
        ranOut: false,
        awaitDrain: 0,
        readingMore: false,
        decoder: null,
        encoding: null },
     readable: false,
     domain: null,
     _events: { end: [Function] },
     _eventsCount: 1,
     _maxListeners: undefined,
     path: 'words/engmix.txt',
     fd: null,
     flags: 'r',
     mode: 438,
     start: undefined,
     end: undefined,
     autoClose: true,
     pos: undefined,
     bytesRead: 794434,
     destroyed: true,
     closed: true }

我修改了电话

createTrie(reader_1, wordList)
  .then((trie) => findCommon(reader_2, trie))
  .then((data) => console.log(data))

为:

createTrie(reader_1, wordList)
  .then((trie) => findCommon(readLine.createInterface({
    input: fs.createReadStream('words/engmix.txt')
  }), trie))
  .then((data) => console.log(data))

这种方式有效。我不确定为什么会这样,但确实如此。

答案 1 :(得分:0)

您可以完全避免承诺和回调,只需使用nsynjs按顺序执行逻辑。逻辑将转变如下:

var nsynjs = require('nsynjs');
var textFile = require('./wrappers/nodeReadline').textFile; // this file is part of nsynjs

function process(textFile) {

    var fh = new textFile();
    fh.open('path/to/file1');
    var s, dict={};
    while (typeof(s = fh.readLine(nsynjsCtx).data) != 'undefined')
        dict[s] = true;
    fh.close();

    fh = new textFile();
    fh.open('path/to/file2');
    while (typeof(s = fh.readLine(nsynjsCtx).data) != 'undefined')
        if(dict[s])
            console.log(s);
    fh.close();

}

var ctx = nsynjs.run(process,{},textFile,function () {
    console.log('done');
});

以上代码基于此示例:https://github.com/amaksr/nsynjs/blob/master/examples/node-readline/index.js