Ситуация следующая. Есть какой-то класс A
, при создании которого в конструкторе на определенный узел DOM должен быть навешен обработчик. При срабатывании события, зарегистрированного этим обработчиком должно вывестись сообщение и вызваться метод _handleCall()
.
Я решил попробовать реализовать при помощи Promise'ов:
class A {
constructor() {
this._waitForCall().then(_handleCall);
}
_waitForCall() {
return new Promise((resolve, reject) => {
let handler = (event) => {
console.log("called.");
resolve(event);
};
this.target.addEventListener("click", handler);
});
}
_handleCall(event) {
console.log(event);
}
}
Однако я заметил, что при таком подходе метод _handleCall
вызывается только один раз, хотя сообщение "called." из обработчика handler
выводится при каждом клике на элементе.
Насколько я понимаю, так происходит потому, что у каждого Promise'а есть некое состояние, которое может измениться только единожды. И после его изменения в "fulfilled" (которое происходит после первого нажатия по элементу), метод then
на Promise'е уже больше никогда вызван не будет. И отсюда первый вопрос: правильно ли я это понимаю?
В общем, я решил, что ситуацию можно исправив, добавив в _handleCall
повторную регистрацию Promise'а:
_handleCall(event) {
console.log(event);
this._waitForCall().then((e) => this._handleCall(e));
}
Однако здесь ситуация тоже неоднозначно. Прежде всего плохо то, что при таком подходе на элементе this.target
обработчик один и тот же будет регистрироваться n
-ое количество раз, что ни есть хорошо. И, хотя эта проблема довольно легко решается, мне все равно кажется, что такой подход - ужасный костыль. Правильно ли я понимаю (и это второй вопрос), что Promise'ы для того и нужны, чтобы обрабатывать какой-то асинхронный код единожды?
Ну и здесь же возникает третий вопрос: а стоит ли вообще работать с событиями и их обработчиками при помощи Promise'ов? Я изначально решил, что стоит, потому что события, они, вроде как, асинхронные. А сейчас принято с любым асинхронным кодом работать при помощи Promise'ов. Но ведь с другой стороны обработчики навешиваются по той же причине. И я с таким же успехом мог бы реализовать все примерно так:
class A {
constructor() {
this._registerCallEventListener(); // просто вызываем метод, навешивающий обработчик
}
_registerCallEventListener() {
let handler = (event) => {
console.log("called.");
this._handleCall(event); // вызываем напрямую
};
this.target.addEventListener("click", handler);
}
_handleCall(event) {
console.log(event);
}
}
В общем, как лучше поступить?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Виртуальный выделенный сервер (VDS) становится отличным выбором
Как вызвать функцию объекта, если имя объекта и имя функции хранятся в переменной?
Мне нужно задать объекту рандомный цветРандомный цвет делает функция, но вопрос в том, как значение этой функции установить в CSS?
Есть попытка создания собственного валидатора для формы в Angular 5 :