Pokio 是一个简单易用的 PHP 异步 API,它只需简单配置即可正常工作!
以下是一个示例:
$promiseA = async(function () {
sleep(2);
return'Task 1';
});
$promiseB = async(function () {
sleep(2);
return'Task 2';
});
// 只需 2 秒钟...
[$resA, $resB] = await([$promiseA, $promiseB]);
echo$resA; // Task 1
echo$resB; // Task 2
在幕后,Pokio 使用 PCNTL 扩展来分叉当前进程,并在子进程中运行给定的闭包。这允许您并发运行多个任务,而不会阻塞主进程。
此外,为了在父进程和子进程之间进行通信,Pokio 使用 FFI 创建一个共享内存段,这允许您快速高效地在进程之间共享数据。
然而,与其他库不同,如果 PCNTL 或 FFI 不可用,Pokio 将自动回退到顺序执行,因此您仍然可以毫无问题地使用它。
“需要 PHP 8.3+ 。
⚡️ 通过 Composer 安装包以开始使用:
composer require nunomaduro/pokio:^0.1
async 全局函数返回一个承诺(promise),它最终将解析由给定闭包返回的值。
$promise = async(function () {
return 1 + 1;
});
var_dump(await($promise)); // int(2)
类似于其他承诺库,Pokio 允许您在承诺上链式调用方法(如 then、catch 等)。
then 方法将在承诺成功解析时被调用。它接受一个闭包,该闭包将接收解析的值作为其第一个参数。
$promise = async(fn (): int => 1 + 2)
->then(fn ($result): int => $result + 2)
->then(fn ($result): int => $result * 2);
$result = await($promise);
var_dump($result); // int(10)
您也可以选择在承诺上链式调用 catch 方法,如果给定闭包抛出异常,它将被调用。
$promise = async(function () {
throw new Exception('Error');
})->catch(function (Throwable $e) {
return 'Rescued: ' . $e->getMessage();
});
var_dump(await($promise)); // string(16) "Rescued: Error"
如果您不想使用 catch 方法,您也可以使用原生的 try/catch 块。
$promise = async(function () {
throw new Exception('Error');
});
try {
await($promise);
} catch (Throwable $e) {
var_dump('Rescued: ' . $e->getMessage()); // string(16) "Rescued: Error"
}
类似于 catch 方法,您也可以在承诺上链式调用 finally 方法,无论承诺是否成功解析或抛出异常,它都会被调用。
$promise = async(function (): void {
throw new RuntimeException('Exception 1');
})->finally(function () use (&$called): void {
echo "Finally called\n";
});
如果您从闭包中返回一个承诺,它将被自动等待。
$promise = async(function () {
return async(function () {
return 1 + 1;
});
});
var_dump(await($promise)); // int(2)
await 全局函数将阻塞当前进程,直到给定的承诺解析。
$promise = async(function () {
sleep(2);
return 1 + 1;
});
var_dump(await($promise)); // int(2)
您也可以将一个承诺数组传递给 await 函数,它将同时等待这些承诺。
$promiseA = async(function () {
sleep(2);
return 1 + 1;
});
$promiseB = async(function () {
sleep(2);
return 2 + 2;
});
var_dump(await([$promiseA, $promiseB])); // array(2) { [0]=> int(2) [1]=> int(4) }
除了使用 await 函数,您也可以直接调用承诺,它将返回承诺的解析值。
$promise = async(fn (): int => 1 + 2);
$result = $promise();
var_dump($result); // int(3)