我无法创建一个继承自EventEmitter的类。 emit()函数最终未定义。这是问题的简化摘录:
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()的角度来看,在Switch对象之外没有任何事情发生。换句话说,我还没有任何事件监听器与Switch绑定。
这里是我如何创建Switch的实例(SunsetSwitch派生自Switch):
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文件:
fs.readdirSync('./switches')
.filter(function (file) {
return file.substr(-5) === '.json';
})
.forEach(function (file) {
switches.push(createSwitch('./switches/' + file));
});
这是我目前收到的错误消息:
未处理拒绝TypeError:self.emit不是函数 在/home/mark/XmasLights/switch.js:65:18 在tryCatcher(/home/mark/XmasLights/node_modules/bluebird/js/release/util.js:11:23) 在Promise._settlePromiseFromHandler(/home/mark/XmasLights/node_modules/bluebird/js/release/promise.js:488:31) 在Promise._settlePromise(/home/mark/XmasLights/node_modules/bluebird/js/release/promise.js:545:18) 在Promise._settlePromise0(/home/mark/XmasLights/node_modules/bluebird/js/release/promise.js:590:10) 在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) 在Immediate.Async.drainQueues [as _onImmediate](/home/mark/XmasLights/node_modules/bluebird/js/release/async.js:16:14) at processImmediate [as _immediateCallback](timers.js:383:17)
以下是如何定义SunsetSwitch的摘录:
var Switch = require('./switch.js');
var SunsetSwitch = function (id, displayName, onOffset, offTime) {
Switch.call(this, id, displayName, null, offTime);
}
module.exports = SunsetSwitch;
答案 0 :(得分:1)
感谢所有回复的人,尤其是jfriend00,他让我走上了解决方案的道路。
问题源于我在定义SunsetSwitch时所做的事情,这是从Switch派生的。
我忽略了将此行包含在SunsetSwitch的模块文件中:
util.inherits( SunsetSwitch, Switch );
基于我对javascript的有限理解,这个遗漏阻止了Switch的原型传播到SunsetSwitch。
我需要记住,在javascript中定义继承树并不像C#那样简单,例如,C#,我有大部分的经验。你必须设置属性--Switch.call(this,id,displayName,null,offTime) - 并复制原型 - util.inherits(SunsetSwitch,Switch)。