Skip to content
Greg Bowler edited this page May 4, 2026 · 1 revision

Timers are the objects the loop watches. Each timer keeps a queue of trigger times, and each time a timer is due it runs every callback attached to it.

IndividualTimer

IndividualTimer is for one-off trigger times.

We can schedule a relative delay in the constructor:

use GT\Async\Timer\IndividualTimer;

$timer = new IndividualTimer(5);

That means "trigger once, five seconds from now".

We can also add absolute trigger times:

$start = microtime(true);

$timer = new IndividualTimer();
$timer->addTriggerTime($start + 1);
$timer->addTriggerTime($start + 5);
$timer->addTriggerTime($start + 10);

addTriggerTime() expects a Unix epoch float, not a delay value.

PeriodicTimer

PeriodicTimer is for repeated work at a fixed interval.

use Gt\Async\Timer\PeriodicTimer;

$timer = new PeriodicTimer(0.25, true);

This timer will trigger every quarter of a second, and because the second argument is true, the first tick is immediate.

If we want the timer to wait before the first tick, use:

$timer = new PeriodicTimer(0.25, false);

Adding and removing callbacks

Any timer can hold more than one callback:

$timer->addCallback(function() {
	echo "A", PHP_EOL;
});

$timer->addCallback(function() {
	echo "B", PHP_EOL;
});

When the timer ticks, both callbacks run in the order they were added.

Callbacks can also be removed:

$callback = function() {
	echo "Only once", PHP_EOL;
};

$timer->addCallback($callback);
$timer->removeCallback($callback);

Running several timers together

The loop can observe any number of timers at once.

use GT\Async\Loop;
use GT\Async\Timer\IndividualTimer;
use GT\Async\Timer\PeriodicTimer;

$loop = new Loop();
$stopTimer = new IndividualTimer(5);
$countdownTimer = new PeriodicTimer(1, true);
$dotTimer = new PeriodicTimer(0.1, true);
$count = 5;

$countdownTimer->addCallback(function() use(&$count) {
	echo "Countdown: $count", PHP_EOL;
	$count--;
});

$dotTimer->addCallback(function() {
	echo ".";
});

$stopTimer->addCallback(function() use($loop) {
	echo PHP_EOL, "Stop", PHP_EOL;
	$loop->halt();
});

$loop->addTimer($countdownTimer);
$loop->addTimer($dotTimer);
$loop->addTimer($stopTimer);
$loop->run();

This is the main idea behind the package: small pieces of work can take turns without us having to block on one long operation.


Next, move on to Deferred work to connect the loop to Deferred objects and promises.

Clone this wiki locally