Categories: Lessons

7 способов сделать таймер в DevelNext и JPHP

Sorry, this entry is only available in Russian. For the sake of viewer convenience, the content is shown below in the alternative language. You may click the link to switch the active language.

Таймеры штука интересная и очень полезная в разработке. Если вы работали только с серверным php, то скорее всего, таймеры вам были не очень-то нужны, максимум, вы использовали cron и больше ничего. В это статье мы рассмотрим 10 способов реализовать таймер в develnext и jphp, расскажем про плюсы и минусы каждого.

1 способ. Примитивный.

Используйте потоки + sleep():

// если надо
// use php\lang\Thread; или use std;

$thread = new Thread(function () {
  while(true) {
    echo "Timer\n"; // код таймера
    sleep(1); // ждем 1 секунду
  }
});

Все что мы делаем – создаем поток, а внутри бесконечный цикл, в каждой итерации ставим паузу на 1 секунду. Вот и весь таймер. Это – самый простой и в то же время, самый не оптимальный таймер на develnext и jphp.

Не делайте так НИКОГДА, читайте ниже, как лучше!

 

2 способ. Класс Timer.

Это встроенный класс в стандартную библиотеку jphp, он доступен и в develnext. Его смело можно использовать, он очень удобен. Класс умеет создавать одноразовые таймеры и таймеры, которые выполняются каждые несколько секунд, часов и т.д. А вот и пример:

// если нужно
// use std; или use php\time\Timer;

$timer = Timer::every(1000, function () {
  // выполняется код каждую секунду.
});

Таймер умеет принимать в качестве периода не только миллисекунды, но и сложные значения, например:

Timer::every('30s', function () { ... }); // каждые 30 секунд.
Timer::every('1m 30s', function () { ... }); // каждые 1.5 минуты
Timer::every('1h 30m', function () { ... }); // каждые полтора часа
Timer::every('1.5h', function () { ... }); // также, каждые полтора часа.

В периодах можно указывать:

  1. s – секунды
  2. m – минуты
  3. h – часы
  4. без буквы – млсек.

Их можно указывать в дробном виде, как в примере выше, комбинировать с несколькими и т.п.

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

Если вы используете DevelNext и в таймере пытаетесь менять GUI, визуальные компоненты, показывать диалоги и все в таком духе, то используйте функцию uiLater(), для того, чтобы не было ошибок (см. подробнее здесь).

Такие таймеры легко останавливать:

$timer = Timer::every('1s', function () { ... });

// где-нибудь в коде, отменить таймер.
$timer->cancel();

Либо можно использовать аргумент функции таймера:

Timer::every('1s', function (Timer $timer) {
    if (/* какое-то условие */) {
        $timer->cancel(); // остановить таймер.
    }
});

У класса также имеется метод для одиночного срабатывания, как setTimeout() из JavaScript:

Timer::after('20s', function () {
   // выполнить 1 раз через 20 секунд.
});

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

 

3 способ. Класс TimerScript.

Этот класс доступен только если вы разрабатываете в DevelNext. По большому счету, этот класс является модульным компонентом и доступен в редакторе модулей. Создать его в коде очень просто и апи у него легкое:

// если нужно
// use frameworkd; или use script\TimerScript;

$timer = new TimerScript();
$timer->interval = 2500; // 2.5 секунды
$timer->repeatable = true; // повторять да/нет
$timer->on('action', function () {
    // событие таймера
});

// запускаем таймер
$timer->start();

Кстати, TimerScript поддерживает в качестве интервала и сложные выражения, как таймер из 2 пункта. Например:

$timer->interval = '2.5s';
$timer->interval = '1m 30s';

Такие значения можно вводить и в самой среде, в редакторе модулей для таймеров.

 

4 способ. Простой.

В самом DevelNext-e есть 2 функции, которые умеют создавать паузу в выполнении кода, аналог sleep().

wait(2500); // ждать 2.5 секунды, но это еще не таймер.

// одноразовый таймер.
waitAsync(2500, function () {
    // код выполнится через 2.5 секунды.
});

Недостаток этого таймера в том, что он может выполнится только один раз, как setTimeout() из JavaScript. Однако он очень удобен тем, что выполняется в UI потоке и синтаксис у него простой и короткий.

 

5 способ. Для Анимации.

Этот таймер является частью JavaFX и DevelNext, он нужен специально для создания плавных анимаций. У этого таймера нет понятия интервала, т.к. он срабатывает в каждый кадр отрисовки, т.е. 1/60 секунды.

$timer = new UXAnimationTimer(function () {
   // код таймера, можно работать с UI.
});
$timer->start(); // запускаем таймер.
$timer->stop(); // останавливаем таймер.

С помощью этого таймера написан класс для анимаций Animation (читайте здесь).

Если вы меняете UI объекты, чтобы создать какую-то анимацию с цветом, с передвижением и т.п., используйте этот таймер. Если не знаете как, посмотрите исходники класса Animation здесь.

 

6 способ. Одно-поточный таймер.

Таймер timer\AccurateTimer основан на классе из предыдущего пункта, однако он добавляет опцию интервала и повторяемости, как, например, TimerScript. Его также можно использовать для анимаций, для UI. Выполняется он в потоке UI, поэтому сильно-нагруженные операции в нем делать не стоит, иначе ваша программа будет лагать и тормозить.

$timer = AccurateTimer(2500, function () {
    // выполнение таймер в потоке UI.
});
$timer->start(); // запускаем таймер.

Реализация этого таймера простая, все в одном потоке, поэтому не стоит создавать более 1000 таких таймеров одновременно. Лучше попробуйте таймер из пункта 2 или 3.

 

7 способ. Таймер-триггер.

В develnext можно запустить таймер-триггер, который сработает тогда, когда сработает определенное условие. Это делается с помощью метода Timer::executeWhile()

TimerScript::executeWhile(function () {
    // если вернуть здесь true, то событие ниже выполнится.
    // return true/false;
}, function () {
    // код таймера-триггера.
});

Можно использовать например в играх.

 

Идея для проекта

На этом все, надеюсь вам было интересно! Таймеры очень интересная штука, их можно использовать в играх и во многих других программах. Попробуйте на основе этой статьи создать свою программу “Будильник”, где можно было бы указывать время срабатывания, указывать мелодию. В этой программе можно было бы использовать компонент “Трей-иконка”, чтобы будильник работал постоянно и звонил когда нужно. В общем, это – еще одна идея для вашего проекта.

Дмитрий Зайцев

View Comments

Share
Published by
Дмитрий Зайцев

Recent Posts

Изолированные окружения в JPHP

Sorry, this entry is only available in Russian. For the sake of viewer convenience, the content is shown below in…

7 years ago

Кто он, автор DevelNext и DevelStudio?

Sorry, this entry is only available in Russian. For the sake of viewer convenience, the content is shown below in…

7 years ago

Топ 7. Скрытые возможности DevelNext

Sorry, this entry is only available in Russian. For the sake of viewer convenience, the content is shown below in…

7 years ago

Осенний DevelNext 16.7.0 уже доступен!

Sorry, this entry is only available in Russian. For the sake of viewer convenience, the content is shown below in…

7 years ago

Встречайте летний DevelNext 16.6.0

Sorry, this entry is only available in Russian. For the sake of viewer convenience, the content is shown below in…

7 years ago

Встречайте DevelNext 16.5.2

Sorry, this entry is only available in Russian. For the sake of viewer convenience, the content is shown below in…

8 years ago