"это" потеряно в вызове setImmediate?
У меня есть ситуация, когда метод должен вызывать себя рекурсивно и асинхронно через setImmediate.
Следующий код не имеет ничего общего с оригиналом, но возникает та же самая "проблема": ссылка "this", похоже, теряется при втором вызове.
function A () {
this.some_message = 'Index is: ';
}
A.prototype.someMethod = function (index) {
console.log(`${this.some_message} ${index}`);
setImmediate(this.someMethod, index + 1);
}
У меня есть следующий вывод, в котором "this.someMethod" в какой-то момент перестает быть функцией, я не понимаю этого:
> 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)
>
Я решил это, изменив последнюю строку метода на:
setImmediate(this.someMethod.bind(this), index + 1);
Но я не понимаю, почему setImmediate ведет себя так. Кто-нибудь может дать мне ссылку на это? Я буду очень признателен за любую помощь. Я пару часов пытался найти ответ. Заранее спасибо.
- редактировать: также, не стесняйтесь предложить лучший заголовок или редакцию. У меня довольно плохой уровень английского.
1 ответ
Каждый раз, когда вы используете функции более высокого порядка, вы потеряете контекст. У вас есть три варианта: сохранить ссылку на this
в закрытии связывайте функцию, которую вы передаете, или не используйте 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);
});
}
};