setTimeout() не может правильно вызывать вложенные функции

У меня есть функция тайм-аута, которая выглядит так:

setTimeout(this.logout, 1000);

метод входа:

  logout() {
    this.auth_token = ""; 
    this.loggedIn = false;
    this.emitLogedInStatusChange();
  }

 isLoggedIn() {
    return this.loggedIn;
  }

  private emitLogedInStatusChange() {
        this.LoggedInStatusChangedEmitter.emit({value: this.loggedIn});
    }

где источник событий сообщает основному компоненту, где значение для loggedIn изменено. Проблема заключается в следующем.emitLogedInStatusChange(); где я получил сообщение об ошибке:

this.emitLogedInStatusChange is not a function

Мой вопрос, как правильно вызвать эту функцию внутри выхода из системы, чтобы setTimeout мог работать?

Вот где я это называю:

map((res) => { 
 if (res.username === username) { 
   this.auth_token = res.access_token; 
   this.sessionId = res.SessionID;  
   this.loggedIn = true; 
   this.expires = res.expires_in; 
   setTimeout(this.logout, this.expires*1000); 
   this.emitLogedInStatusChange(); 
  }

4 ответа

При передаче функций и методов всегда необходимо следить за тем, как это влияет на this, По умолчанию JS использует область вызова.

Есть способы явно указать область, которая будет использоваться:

setTimeout(this.logout.bind(this), 1000);

но я не могу быть уверен, потому что ваш код не показывает, откуда код вызывается.

альтернативно

setTimeout(() => this.logout(), 1000);

можно использовать, но это кажется менее кратким. Для других случаев использования, когда параметры передаются в обратный вызов, они должны повторяться, как

someFunction((a, b, c) => this.logout(a, b, c), 1000);

Есть две альтернативы для решения вашей проблемы, первая (как предлагают другие ответы) - это привязка вызова вашего метода к this чтобы сохранить контекст.

setTimeout(this.logout.bind(this), 1000);

Второе решение - объявить logout как переменную, чтобы вы не теряли контекст при его вызове:

logout = () => {
    this.auth_token = ""; 
    this.loggedIn = false;
    this.emitLogedInStatusChange();
}

и тогда вы называете это так:

setTimeout(this.logout, 1000);

setTimeout добавит вызов функции в цикл обработки событий и запустит его оттуда. Так this потерян и установлен в window(дефолт). Вам придется связать this к вашей функции.

setTimeout(this.logout.bind(this), 1000);

Вы передаете функцию в setTimeout().

Я бы рекомендовал использовать анонимную функцию, которая вместо этого вызывает нужную функцию:

setTimeout(function(){
    this.logout();
}, 1000);
Другие вопросы по тегам