I have a situation where a method must call itself recursively, and asynchronously, via setImmediate.
The next code doesn't have any to do with the original, but the same "problem" arises: the "this" reference seems to be lost on the second call.
function A () {
this.some_message = 'Index is: ';
}
A.prototype.someMethod = function (index) {
console.log(`${this.some_message} ${index}`);
setImmediate(this.someMethod, index + 1);
}
I have the next output, in where "this.someMethod", at some point, stops being a function, i'm not understanding it:
> new A().someMethod(1)
Index is: 1
undefined
> undefined 2
TypeError: "callback" argument must be a function
at exports.setImmediate (timers.js:664:11)
at Immediate.A.someMethod (repl:3:1)
at runCallback (timers.js:639:20)
at tryOnImmediate (timers.js:610:5)
at processImmediate [as _immediateCallback] (timers.js:582:5)
>
I solved it by changing the last line of the method to:
setImmediate(this.someMethod.bind(this), index + 1);
But i don't understand why setImmediate behaves like that. Can anyone provide me some link about it? I will really appreciate any help. I've been a couple of hours trying to find the answer. Thanks in advance.
-- edit: An also, feel free to suggest a better title or redaction. I have a pretty poor english level.
Any time you are using higher-order functions, you will lose the context. You have three options: store a ref to this
in a closure, bind the function you pass around, or don't use this
.
// using Function.prototype.bind
var foo = { value: 3 };
foo.method = function() { return this.value };
function doesAsync() {
setImmediate(foo.method.bind(foo));
}
// using a closure
var bar = {
value: 3,
method: function() {
var self = this;
setImmediate(function() {
alert(self.value);
});
}
};