首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >nodejs:继承EventEmitter

nodejs:继承EventEmitter
EN

Stack Overflow用户
提问于 2016-01-23 17:07:11
回答 1查看 1K关注 0票数 0

我无法创建继承自EventEmitter的类。函数的结果是未定义。下面是一个简化的问题摘录:

代码语言:javascript
复制
var EventEmitter = require( 'events' );
var util = require( 'util' );
var zWave = require('./zWaveRequest.js');
var CronJobManager = require( 'cron-job-manager' );
var timespanToCron = require( './parseTime.js' ).timespanToCron;
var winston = require( './logger.js' );

const levelCronName = 'level';

var Switch = function (id, displayName, onTime, offTime) {
    var _nodeNum;
    var _nodeName;
    var _lastLevel = -1;
    var _levelPollInterval = config.levelPollInterval;
    var _levelTS = 0;
    var _cronMgr = new CronJobManager( );

    EventEmitter.call( this );

    var self = this;

    function initLevelJob() {
        // the log shows self.emit() doesn't exist (???)
        if( typeof self.emit === 'function' ) winston.info( 'initLevelJob(): self.emit() is defined' );
        else winston.info( 'initLevelJob(): self.emit() is NOT defined' );

        _cronMgr.add( levelCronName, timespanToCron( _levelPollInterval ), function() {
            self.getLevel();
        }, 
        {
            start: true,
        } );
    }

    this.getLevel = function() {
        zWave.curLevel( _nodeNum )
        .then( function( value ) {
            _lastLevel = value;
            _levelTS = Date.now( );

            // this next call always fails with an 'emit is not a function' error
            self.emit( 'level', self.lastLevel, self.lastLevelTS );
        } );
    }

    Object.defineProperties(this, {
        nodeNumber: {
            get: function() { return _nodeNum; },
            set: function( val ) {
                _nodeNum = val;
                initLevelJob( );
            },
        },

        levelPollInterval: {
            get: function() { return _levelPollInterval; },
            set: function( val ) {
                _levelPollInterval = val;
                initLevelJob( );
            }
        },
}

util.inherits( Switch, EventEmitter );

module.exports = Switch;

这里的总体想法是将cronjob设置为ping另一个服务器以获取信息(即对zWave的调用)。cronjob回调更新一些内部变量,然后发出一个事件。

但是self.emit()是未定义的,尽管我认为我遵循的是如何从EventEmitter继承的示例。

调用代码

从我现在如何使用emit()的角度来看,开关对象之外什么都不会发生。换句话说,我还没有将任何事件侦听器绑定到开关中。

下面是我如何创建交换机实例(SunsetSwitch是从交换机派生的):

代码语言:javascript
复制
function createSwitch( switchFile ) {
    var raw = JSON.parse( fs.readFileSync( switchFile ) );
    var retVal;

    if( typeof raw.onTime === 'undefined' ) {
        // sunset switch
        retVal = new SunsetSwitch( );

        if( config.forceImmediateOn ) {
            var now = new Date( );

            var sunset = sunCalc.getTimes( now, config.latitude, config.longitude ).sunset;
            retVal.onOffset = Math.ceil( ( now - sunset ) / 60000 ) - 5;

            var turnOff = new Date( now );
            turnOff.setMinutes( now.getMinutes( ) + config.testMode.duration.totalMinutes() );
            retVal.offTime = turnOff;

            retVal.basedOnSunrise = raw.basedOnSunrise;
        }
        else {
            retVal.onOffset = raw.onOffset;
            retVal.offTime = raw.offTime;
            retVal.basedOnSunrise = raw.basedOnSunrise;
        }
    }
    else {
        // regular switch
        retVal = new Switch( );

        retVal.offTime = raw.offTime;
        retVal.onTime = raw.onTime;
    }

    if( config.forceImmediateOn ) retVal.ignoreInitialOff = false;
    else {
        if( typeof raw.ignoreInitial != 'boolean' ) retVal.ignoreInitialOff = true;
        else retVal.ignoreInitialOff = raw.ignoreInitialOff;
    }

    retVal.displayName = raw.displayName;
    retVal.nodeName = raw.nodeName;
    retVal.nodeNumber = raw.nodeNumber;

    return retVal;
}

createSwitch()是从读取一堆json文件的文件系统循环中调用的:

代码语言:javascript
复制
fs.readdirSync('./switches')
.filter(function (file) {
    return file.substr(-5) === '.json';
})
.forEach(function (file) {
    switches.push(createSwitch('./switches/' + file));
});

下面是我目前收到的错误消息:

未处理的拒绝(/home/mark/XmasLights/node_modules/bluebird/js/release/util.js:11:23):self.emit不是在/home/mark/XmasLights/Swit.js:65:18 at tryCatcher self.emit at Promise._settlePromiseFromHandler (/home/mark/XmasLights/node_modules/bluebird/js/release/promise.js:488:31) at Promise._settlePromise (/home/mark/XmasLights/node_modules/bluebird/js/release/(/home/mark/XmasLights/node_modules/bluebird/js/release/promise.js:590:10) at Promise._settlePromises (/home/mark/XmasLights/node_modules/bluebird/js/release/promise.js:673:18) at Async._drainQueue (/home/mark/XmasLights/node_modules/bluebird/js/release/async.js:125:16) at Async._drainQueues (/home/mark/XmasLights/node_modules/bluebird/js/release/async.js:135:10) at Immediate.Async.drainQueues onImmediate at processImmediate immediateCallback

以下是如何定义SunsetSwitch的摘录:

代码语言:javascript
复制
var Switch = require('./switch.js');

var SunsetSwitch = function (id, displayName, onOffset, offTime) {
    Switch.call(this, id, displayName, null, offTime);
}

module.exports = SunsetSwitch;
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-23 19:15:59

感谢所有回应的人,特别是jfriend00,他们让我找到了解决方案的道路。

这个问题源于我在定义SunsetSwitch时没有做的一些事情,这是从交换机派生出来的。

我忽略了在SunsetSwitch的模块文件中包括这一行:

代码语言:javascript
复制
util.inherits( SunsetSwitch, Switch );

基于我对javascript的有限理解,这一遗漏阻止了原型被传播到SunsetSwitch。

我需要记住,在javascript中定义继承树并不像在C#中那样简单,因为我在这里积累了大部分经验。您必须同时设置属性-- Switch.call(this,id,displayName,null,offTime) --并复制原型-- util.inherits( SunsetSwitch,Switch )。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34966319

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档