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);