It's very strange. I have code:
var client = {
init: function () {
this.connect();
return this;
},
connect: function () {
var clientObj = this;
this.socket = net.connect({
port: config.port,
host: config.host
}, function () {
log_ts('Connected to serv');
});
this.socket.on('data', this.dataParser);
this.socket.on('end', function () {
logerr_ts('Disconnected from serv');
logerr_ts('Trying to reconnect after '+config.reconnectTimeout + 'ms');
setTimeout(clientObj.connect, config.reconnectTimeout);
});
},
dataParser: function (data) {
//analyzing data from me6d server
}
};
Now when it became disconected from serv, it's trying to reconnect and i'm getting this error:
2015-04-12 15:22:12 Trying to reconnect after 500ms
events.js:142
throw TypeError('listener must be a function');
^
TypeError: listener must be a function
at TypeError (native)
at Socket.addListener (events.js:142:11)
at Socket.Readable.on (_stream_readable.js:671:33)
at me6dClient.connect [as _onTimeout] (/var/www/nodejs/client/index.js:212:15)
at Timer.listOnTimeout (timers.js:110:15)
How it can be? this.dataParser is a function. may be it's somethink became bad when timeout is fired, it changes context for this ? But how?)
Answer
The problem is that using clientObj.connect
as a reference will lose the context it's bound to.
You can rebind it like so:
setTimeout(clientObj.connect.bind(clientObj), ...);
This basically means "when the timeout is reached, call clientObj.connect
using clientObj
as this
".
FWIW, the same is happening here:
this.socket.on('data', this.dataParser)
The dataParser
method will also be called without the right context. That issue (if it actually is an issue) can be solved in a similar fashion.
No comments:
Post a Comment