Работа таймеров в правилах WB

Здравствуйте!
В последнее время осуществлял немалый объём работы с таймерами в правилах WB и документация немного запутала в том, как на самом деле работают таймеры.
Приведу пример, в чем возникла проблема:
Писал правило, которое при срабатывании условия по прошествии 5 секунд переводило бы переменную в true. Тип правила - asSoonAs, и, если условие становится ложным, таймер должен останавливаться при помощи метода stop() (если таймер активен, конечно же)
Также привожу примерный код:

defineRule("rule1", {
    asSoonAs: function() {
        var condition = dev["dev1/dep"];

        // Если условие ложно и переменная "горит"
        if ( !condition && dev["dev1/ch1"] ) {
            dev["dev1/ch1"] = false;
        }

        // Если условие ложно, остановить таймер
        if ( !condition ) {
            timers.timer.stop();
        }

        return condition;
    },

    then: function() {
        startTimer("timer", 5000);
    }
});

Также правило по срабатыванию таймера:

defineRule("rule1_handler", {
    asSoonAs: function() {
        return timers.timer.firing;
    },
    then: function() {
        dev["dev1/ch1"] = true;
    }
});

Проблема возникла следующая: таймер срабатывал в самые непредсказуемые моменты, т.е тогда, когда condition явно не горел 5 секунд.
Через некоторое время возникла теория, что метод stop() приостанавливает таймер, но не останавливает его полностью. Т.е следующий раз, когда таймер запущен, он возобновляется. Правда ли это?
Следовательно, как лучше поступить в этой ситуации, если нужно, чтобы таймер полностью сбрасывался?
Видел функцию clearTimeout(), ее можно применить к startTimer()? И будет она работать по другому (в сравнение с методом stop())? Возвращает ли startTimer() идентификатор таймера?
И в целом по коду: хорошая ли практика проверять условие остановки таймера и соответственно останавливать его в asSoonAs части правила или лучше реализовать по другому?
P.S: проверил бы экспериментально, но такой возможности, к сожалению, пока нет, да и хотелось бы получить полное разъяснение данной проблемы
Заранее большое спасибо!

Да, объект таймера явно не освобожденный и не сработавший - надо явно очищать. Пример можно посмотреть тут: Примеры правил — Wiren Board
Но, тем не менее - он не срабатывает даже если этого не делатьнаписал для попытки воспроизвести:

var test_timer_1_id = null;
qq111
startTicker("forLog", 1000)

defineRule("LogRule", {
  when: function () { return timers.forLog.firing; },
  then: function () {
    log.info("Таймер лога сработал")
    startTimer("smallTimer", 500)
    timers.mainTimer.stop()
  }
})

defineRule("TestRule", {
  when: function () { return timers.mainTimer.firing; },
  then: function () {
    log.info("сработал setTimeout. Его id:", test_timer_1_id);
    test_timer_1_id = null;
  }
})
defineRule("SmallTimerRule", {
  when: function () { return timers.smallTimer.firing; },
  then: function () {
    log.info("сработал smallTimer.");
    test_timer_1_id = startTimer("mainTimer", 2000);
  }
})


log.info("запустили все таймеры.");

Если б таймер продолжал работу - сработал бы “TestRule”. А этого не происходит.

2024-08-01 17:48:25запустили все таймеры.
2024-08-01 17:48:26Таймер лога сработал
2024-08-01 17:48:26сработал smallTimer.
2024-08-01 17:48:27Таймер лога сработал
2024-08-01 17:48:27сработал smallTimer.
2024-08-01 17:48:28Таймер лога сработал
2024-08-01 17:48:28сработал smallTimer.
2024-08-01 17:48:29Таймер лога сработал
2024-08-01 17:48:29сработал smallTimer.
2024-08-01 17:48:30Таймер лога сработал
2024-08-01 17:48:30сработал smallTimer.
2024-08-01 17:48:31Таймер лога сработал
2024-08-01 17:48:31сработал smallTimer.

Как написано в документации " clearInterval(id) является alias’ом clearTimeout() ."

Предполагаю что создаются лишние экземпляры таймеров. Если он явно один - то целесообразно использовать setTimeout() и отслеживать его идентификатор.

1 лайк

Спасибо за ответ и подробное объяснение!
Осуществил код по такому принципу:

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