Szopen Xiao

php setTimeout 函数

2016-07-08

技术依赖

  • 需要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);
comments powered by Disqus