"это" потеряно в вызове 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);
    });
  }
};
Другие вопросы по тегам