Senbonzakuraa
@Senbonzakuraa
Начинаю начинать

Почему событие срабатывает несколько раз?

Основной класс:

class Random {
        constructor(timer) {
            this.timer = timer
            this.status = 0
            this.emitter = new EventEmitter()
        }
        async setStatus() {
            const interval = setInterval(()=> {
                this.timer -= 1
                if(this.timer <= 0) {
                    this.status = 1
                    this.emitter.emit('end', this.status)
                }
            }, 1000)
        }
    
}

Клиентский код:
const Random = require('../Random').Random
const chanels = {}
const timers = [{timer: 20, name: "chanel1"},{timer: 400, "chanel2"}]
timers.map((timer,id) => chanels[timer.name] = new Random(timer.time))
socket.on('startTimer', async (name, callback) => {
    await chanels[name].setStatus()
    chanels[name].emitter.on('end', (data)=> {
        console.log(data) //Выводит несколько раз подряд содержимое Data
    })
})

Я думал, что это возможно из-за того, что каждый раз при коннекте юзера создается новый слушатель события chanels[name].emitter.on('end'), но я пробовал ставить вместо on - once, но все равно событие срабатывает рандомное кол-во раз. Пробовал очищать слушателей chanels[name].emitter.removeAllListeners(['end']); перед созданием нового, но результат тот же. Почему так происходит?
  • Вопрос задан
  • 273 просмотра
Решения вопроса 1
lastuniverse
@lastuniverse
Всегда вокруг да около IT тем
у вас 2 косяка в коде.

Первый вы поняли сами, каждый раз при коннекте вы запускаете новый слушатель события "end", и даже если событие возникнит 1 раз, а слушатели стоят как once то все равно сработает каждый из уже запущенных, но еще ни разу не сработавших слушателей.

Второй косяк - это то что вы не завершаете запущенный setInterval, который каждую секунду продолжает уменьшать таймер, даже после того как таймер станет меньше нуля. В результате, когда таймер достигает нуля у вас начинает срабатывать условие if(this.timer <= 0) на каждый тик
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы