1. Go to this page and download the library: Download sue/coroutine library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
use React\Promise\Deferred;
use function Sue\EventLoop\loop;
use function Sue\EventLoop\setTimeout;
use function Sue\Coroutine\co;
$deferred = new Deferred();
setTimeout(3, function () use ($deferred) {
$deferred->resolve('foo');
})
//1. 传统基于thenable方法处理promise
$deferred->promise()->then(function ($value) {
echo "promise value: {$value}\r\n";
});
//2. 使用协程的方式处理promise
co(function ($promise) {
echo "start waiting promise to be resolved\r\n";
$value = yield $promise; //协程会在此处暂停,直到promise被resolve或者reject
echo "promise value: {$value}\r\n"
}, $deferred->promise());
loop()->run();
use function Sue\EventLoop\loop;
use function Sue\Coroutine\co;
$callable = function ($worker_id) {
$count = 3;
while ($count--) {
echo "{$worker_id}: " . yield $count . "\r\n";
}
};
co($callable, 'foo');
co($callable, 'bar');
loop()->run();
/** expect out:
foo: 2
bar: 2
foo: 1
bar: 1
foo: 0
bar: 0
**/
namespace App\Custom;
class CustomCoroutine extends \Sue\Coroutine\Coroutine
{
public function get()
{
$result = parent::get();
Log::info('result got', ['data' => $result]);
}
}
coAs(\App\Custom\CustomCoroutine::class, $callable);
use function Sue\EventLoop\loop;
use function Sue\EventLoop\setInterval;
use function Sue\Coroutine\defer;
setInterval(1, function () {
echo "tick\r\n";
});
$callable = function ($worker_id) {
$count = 3;
while ($count--) {
echo "{$worker_id}: " . yield $count . "\r\n";
}
};
defer(5, $callable, 'foo');
defer(5, $callable, 'bar');
loop()->run();
/** expect out:
tick
tick
tick
tick
tick
foo: 2
bar: 2
foo: 1
bar: 1
foo: 0
bar: 0
tick
tick
...
**/
use Sue\Coroutine\SystemCall;
use function Sue\Coroutine\SystemCall\sleep;
use function Sue\EventLoop\loop;
use function Sue\EventLoop\setInterval;
setInterval(1, function () {
echo "tick\r\n";
});
$callable = function ($worker_id) {
echo "before-sleep\n";
yield SystemCall\sleep(3); //协程会在这里sleep 3秒后再执行
$count = 3;
while ($count--) {
echo "{$worker_id}: " . yield $count . "\r\n";
}
};
co($callable, 'foo');
loop()->run();
/** expect out:
before-sleep
tick
tick
tick
foo: 2
foo: 1
foo: 0
tick
tick
...
**/
use React\Promise\Deferred;
use Sue\Coroutine\SystemCall;
use Sue\Coroutine\Exceptions\TimeoutException;
use function Sue\EventLoop\loop;
use function Sue\EventLoop\setTimeout;
use function Sue\Coroutine\co;
$deferred = new Deferred();
$loop->addTimer(3, function () use ($deferred) {
$deferred->resolve('foo'); //3秒后promise fulfill
});
$promise = $deferred->promise();
$children = (function () use ($promise) {
yield SystemCall\timeout(2); //当前协程最多运行2秒
return yield $promise;
})();
co(function () use ($children) {
try {
yield $children;
} catch (TimeoutException $e) {
//子协程超出最大运行时间时的异常处理
}
});
loop()->run();
use Sue\Coroutine\SystemCall;
use Sue\Coroutine\Exceptions\CancelException;
use function Sue\Coroutine\co;
use function Sue\EventLoop\loop;
$children = (function () {
if (someConditionNotMatch()) {
yield SystemCall\cancel('condition not match', 500);
}
});
co(function () use ($children) {
try {
yield $children;
} catch (CancelException $e) {
//子协程取消异常处理
}
});
loop()->run();