carno-php/coroutine

1.0.1 2019-07-26 02:44 UTC

This package is auto-updated.

Last update: 2024-08-29 04:42:30 UTC


README

安装

composer require carno-php/coroutine

概念

使用协程进行合作式多任务处理(在PHP中!)

yield值

生成器

当yield一个函数并且返回一个生成器(函数中的yield),工作将会旋转并有机会执行其他任务,一些像defer这样的函数依赖于这个特性

承诺

yield一个Promise将会让协程在挂起时休眠,并在承诺解决或拒绝时唤醒,通常与异步IO一起使用

系统调用

Syscall可以让协程中的用户获取任务属性或与任务交互,例如获取任务ID或ctx

函数

Carno\Coroutine中的命名空间

go

创建没有结果但如果有错误会抛出异常的新协程

function go(mixed $program, Context $ctx = null) : void

用法

// use closure
go(function () {
    yield 'something';
    return 'done';
});

// with exceptions
try {
    go(function () {
        throw new Exception('test');
    });
} catch (Throwable $e) {
    echo 'got exception :: ', $e->getMessage(), PHP_EOL;
}

co

类似于go,但返回closure,你可以稍后执行它

function co(mixed $program, Context $ctx = null) : Closure

用法

$func = co(function (string $input) {
    yield 'something';
    echo $input;
});
$func('vars');

async

goco命令的基础,返回一个与协程结果同步的承诺

返回的承诺将在协程完成时解决,或在协程抛出异常时拒绝

function async(mixed $program, Context $ctx = null, mixed ...$args) : Promised

用法

async(function () {
    yield msleep(500);
})->then(function () {
    echo 'you will see me after 500ms', PHP_EOL;
});

await

用于处理异步IO事件的代理,支持超时

function await(Closure $dial, Closure $awake,
    int $timeout = 60000, string $error = TimeoutException::class, string $message = '') : Promised

用法

$async = function ($callback) {
    $callback(111, 222);
};
yield await(function (Closure $awake) use ($async) {
    $async($awake);
}, function (int $a, int $b) {
    echo 'a = ', $a, ' b = ', $b, PHP_EOL;
});

timeout

创建一个在N毫秒后抛出异常的承诺,如果在此期间没有人拒绝它,与race一起使用很有用

function timeout(int $ms, string $ec = TimeoutException::class, string $em = '') : Promised

用法

yield race(timeout(rand(5, 10)), timeout(rand(5, 10), CustomException::class, 'custom message'));

msleep

创建一个在N毫秒后解决的承诺

function msleep(int $ms, Closure $do = null) : Promised

用法

// make sleep
yield msleep(200);
// do something when wake
echo 'you will see hello -> ', yield msleep(300, function () {
    return 'hello';
}), PHP_EOL;

ctx

在协程中获取任务的ctx

用法

go(function () {
    echo 'hello ', (yield ctx())->get('hello'), PHP_EOL;
}, (new Context)->set('hello', 'world'));

defer

defer语句将函数的执行推迟到外围函数返回时

用法

yield (function () {
    yield defer(function ($stage) {
        // $stage is returned value or last yield value or throwable if exception
        echo 'in defer', PHP_EOL;
    });
    echo 'in end', PHP_EOL;
})();

race

与承诺的race有相同的效果,但接受PromisedGeneratorContext

用法

yield race((function () {
    echo 'hello ', (yield ctx())->get('hello'), PHP_EOL;
})(), timeout(500), (new Context)->set('hello', 'world'));

all

race有相同的语法