【发布时间】:2016-04-30 05:03:55
【问题描述】:
我无法创建从 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));
});
这是我目前收到的错误消息:
未处理的拒绝类型错误: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) 在 Async._drainQueue (/home/mark/XmasLights/node_modules/bluebird/js/release/async.js:125:16) 在 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) 在 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;
【问题讨论】:
-
构造函数内部是否定义了
this.emit? -
你使用的是什么版本的节点?
-
另外,您在实例化时是使用
new Switch()还是仅使用Switch()? -
我使用的是 v5.1.0。我正在通过 new Switch() 创建实例,
-
您的问题可能与您如何使用实例化对象有关,因此我们需要查看该代码。子类化本身(您已显示)看起来不错。
标签: javascript node.js inheritance