Coroutines


Coroutines - это подпрограммы на базе yield, которые позволяют
организовать псевдомногопоточность на одной ветке исполнения процесса.

// Простейшее использовании coroutines - это генераторы:

function generator($start, $end, $step = 1) {
    for ($i=$start; $i<=$end; $i+=$step) {
        yield $i;
    }
}

foreach (generator(1,10) as $x) {
    echo $x, "n";
}

// Еще одно применение: функции с постоянной обратной связью

function logger($name) {
    echo "$namen";
    while (true) {
        fputs(STDOUT, yield."n");
    }
}

$logger = logger('New log stream');
$logger->send('Value A');
$logger->send('Value B');
$logger->send('Value C');

// С помощью yield можно и принимать и возвращать значения:

function F() {
    $z = (yield " yield1 ");
    echo 'F1:'.$z;
    $z = (yield " yield2 ");
    echo 'F2:'.$z;
}

$x = F();
$g1 = $x->current();
echo 'G1:'.$g1;
$g2 = $x->send(' ret1 ');
echo 'G2:'.$g2;
$g3 = $x->send(' ret2 ');
echo 'G3:'.$g3;

На выходе: G1: yield1 F1: ret1 G2: yield2 F2: ret2 G3:

// Внутрь coroutine можно посылать ошибки "снаружи"

function gen() {
    echo "Foon";
    try {
        yield;
    } catch (Exception $e) {
        echo "Exception: {$e->getMessage()}n";
    }
    echo "Barn";
}

$gen = gen();
$gen->rewind(); // "Foo"
$gen->throw(new Exception('Test'));