So, I'm trying the Ticker, Event Emitter Exercises from Hands On Node.js
I have this code:
var EventEmitter = require('events').EventEmitter,
util = require('util');
// Ticker Constructor
var Ticker = function (interval) {
this.interval = interval;
this.pulse = null;
}
util.inherits(Ticker, EventEmitter);
Ticker.prototype.start = function() {
this.emit('start');
this.tick();
}
Ticker.prototype.stop = function() {
if (this.pulse != null) clearTimeout(this.pulse);
this.emit('stop');
}
Ticker.prototype.tick = function() {
this.emit('tick');
this.pulse = setTimeout(this.tick, this.interval);
}
var ticker = new Ticker(1000);
ticker.on('start', function() { console.log('Ticker: Start'); });
ticker.on('tick', function() { console.log('Ticker: Tick'); });
ticker.on('stop', function() { console.log('Ticker: Stop'); });
ticker.start();
Which outputs the following, when run:
Ticker: Start Ticker: Tick
timers.js:103
if (!process.listeners('uncaughtException').length) throw e;
^
TypeError: Object #<Object> has no method 'emit'
at Object.Ticker.tick [as _onTimeout] (/Users/twilson/Projects/tutorials/node/ticker-01.js:23:8)
at Timer.list.ontimeout (timers.js:101:19)
Where line ticker-01.js:23
is this.emit('tick');
of the Ticker.prototype.tick
function.
Help, as I really can't see what on earth is going wrong, bound to be a scoping thing no doubt? :(
When calling setTimeout(this.tick, this.interval)
the tick
method will execute within the default context, not what this
refers to right there. You need to either...
Bind the value of this
to the ticker instance:
setTimeout(this.tick.bind(this), this.interval)
Or save a reference to the ticker instance:
var self = this;
setTimeout(function() {
self.tick();
}, this.interval);