如何正确删除类中的事件侦听器?

时间:2017-12-30 18:07:48

标签: javascript node.js javascript-events

我在Windows 7中使用node.js 8.9.3。我正在编写一个类,它在构造函数中自动读取文件的第一部分("标题")使用流和byline npm包。标头中的数据使用事件处理和data中的本机byline事件传递给处理函数。读取文件头中的最后一行后,应暂停流,应删除data事件的现有侦听器,并添加另一个使用不同处理函数的侦听器。所以本质上我将一个处理函数替换为另一个处理函数。

我遇到的问题是,即使我试图专门删除标题处理函数,并且我已成功附加后续处理函数,标题函数仍继续处理来自删除后的data事件。换句话说,即使在使用removeListener删除旧的处理函数之后,新的数据处理函数和旧的标题处理函数仍继续在标题之后的每个新行上使用

这是我的代码,删除了不相关的部分:

const fs = require('fs'),
    path = require('path'),
    byline = require('byline'),
    EventEmitter = require('events');

class VCFStream extends EventEmitter{

    constructor(vcfPath){
        super();

        this.header = [];
        this.variants = {};

        this.stream = byline.createStream(fs.createReadStream(
            vcfPath, { encoding: 'utf8' }));

        this.stream.on('data', this.headerParse.bind(this));

        this.stream.on('end', function(){
            console.log('Stream is done');
            self.emit('end');
        });
    }

    headerParse(line){
        var self = this;
        if(line.startsWith('#CHROM')){
            //This is the last line of the header.
            line.split('\t').splice(9).forEach(function(samp){
                self.samples.push(samp);
            });
            this.stream.pause();
            // I've also tried using this.headerParse
            // and this.headerParse.bind(this)
            // and this.headerParse()
            this.stream.removeListener('data', self.headerParse);
            //Attaching the event listener to process new data after the header
            this.stream.on('data', self.variantParse.bind(self));
            this.header.push(line);
            this.emit('header');
            console.log('header');
            return;
        }
        this.header.push(line);
    }

    variantParse(line){
        let contig = line.split('\t')[0];
        if(!this.variants.hasOwnProperty(contig)){
            this.variants[contig] = [];
        }
        this.variants[contig].push(line);
    }

    /*
        I've also tried using the below class method, 
        calling this.removeHeaderListener() instead of
        this.stream.removeListener('data', self.headerParse);
    */  
    removeHeaderListener(){
        this.stream.removeListener('data', this.headerParse);
    }
}

module.exports = VCFStream;

如果我在console.log(line)方法中粘贴headerParse(),它会在删除侦听器后继续记录每一行事件。

0 个答案:

没有答案