Monday 26 September 2016

javascript - Strange with nodejs/js in using "this" after callback in setTimeout




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

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...