Icicle uses Awaitables and Generators to create Coroutines.

require __DIR__ . '/vendor/autoload.php';

use Icicle\\Awaitable;
use Icicle\\Coroutine\\Coroutine;
use Icicle\\Loop;

$generator = function (float $time) {
    try {
        // Sets $start to the value returned by microtime() after approx. $time seconds.
        $start = yield Awaitable\\resolve(microtime(true))->delay($time);

        echo "Sleep time: ", microtime(true) - $start, "\\n";

        // Throws the exception from the rejected awaitable into the coroutine.
        return yield Awaitable\\reject(new Exception('Rejected awaitable'));
    } catch (Throwable $e) { // Catches awaitable rejection reason.
        echo "Caught exception: ", $e->getMessage(), "\\n";
    }

    return yield Awaitable\\resolve('Coroutine completed');
};

// Coroutine sleeps for 1.2 seconds, then will resolve with a string.
$coroutine = new Coroutine($generator(1.2));
$coroutine->done(function (string $data) {
    echo $data, "\\n";
});

Loop\\run();