技术依赖
- 需要PHP 5.5 以上,支持生成器
- 需要支持 ticks
实现代码
<?php
//enable ticks
declare (ticks = 1);
//setTimeout event list
$timeoutQueue = new SplObjectStorage;
register_tick_function(function() {
global $timeoutQueue;
foreach ($timeoutQueue as $gen) {
$v = $gen->current();
if (is_callable($v)) {
$v();
$timeoutQueue->detach($gen);
}
$gen->next();
}
});
register_shutdown_function(function() {
global $timeoutQueue;
while($timeoutQueue->count()) {
foreach ($timeoutQueue as $gen) {
$v = $gen->current();
if (is_callable($v)) {
$v();
$timeoutQueue->detach($gen);
}
$gen->next();
}
usleep(1000);
}
});
/**
*
* @global SplObjectStorage $timeoutQueue
* @param Generator $gen
*/
function clearTimeout(Generator $gen) {
global $timeoutQueue;
$timeoutQueue->detach($gen);
}
/**
* Calls a function or executes a code snippet after a specified delay.
*
* @global SplObjectStorage $timeoutQueue
* @param callable $callback
* @param int $time millisecond
* @return Generator
*/
function setTimeout(callable $callback, int $time) : Generator{
global $timeoutQueue;
$end = microtime(true) * 1000 + $time;
$f = function($callback, $end) {
while (true) {
if (microtime(true)*1000 >= $end) {
yield $callback;
break;
} else {
yield;
}
}
};
$gen = $f($callback, $end);
$timeoutQueue->attach($gen);
return $gen;
}
setTimeout(function() {
echo '3 second call';
},3000);