clue / block-react
Requires
- php: >=5.3
- react/event-loop: ^1.2
- react/promise: ^3.0 || ^2.7 || ^1.2.1
- react/promise-timer: ^1.5
Requires (Dev)
- phpunit/phpunit: ^9.3 || ^5.7 || ^4.8.35
- react/http: ^1.4
README
此包已迁移到 reactphp/async,仅为了向后兼容。
composer require "react/async:^4 || ^3 || ^2"
仅将 await()
函数及其可选参数 $loop
和 $timeout
合并,其余的 await()
从最新版本 v1.5.0
开始按原样工作,没有其他重大更改。只需更新您的代码以使用更新的命名空间,如下所示
// old $result = Clue\React\Block\await($promise); // new $result = React\Async\await($promise);
有关更多详细信息,请参阅 reactphp/async。
以下文档适用于此包的最后一个版本。进一步的开发将在更新的 reactphp/async 中进行,因此强烈建议您尽快升级。
遗留的 clue/reactphp-block
轻量级库,简化了在传统阻塞环境中集成为 ReactPHP 构建的异步组件。
ReactPHP 为您提供了一组出色的基础组件和庞大的第三方库生态系统,以执行异步操作。事件驱动范式和对任意数量流实时进行异步处理,使您能够构建一套全新的应用程序。这对于从头开始构建现代、可扩展的应用程序非常出色,并可能导致您依赖全新的软件架构。
但是,让我们面对现实:您的日常业务可能无法让您从头开始构建一切并丢弃现有的生产环境。这正是这个库发挥作用的地方
让我们阻塞 ReactPHP 更具体地说,这个库简化了将异步组件集成到您的传统同步(阻塞)应用程序堆栈中的痛苦。
目录
支持我们
我们投入了大量时间开发、维护和更新我们出色的开源项目。您可以通过 在 GitHub 上成为赞助商 来帮助我们维持我们工作的这种高质量。赞助商将获得许多回报,有关详细信息,请参阅我们的 赞助页面。
让我们将这些项目提升到下一个层次!🚀
快速入门示例
以下示例代码演示了如何使用此库与异步 HTTP 客户端一起使用,以处理两个非阻塞 HTTP 请求,并在第一个(更快)的请求解决之前进行阻塞。
function blockingExample() { // this example uses an HTTP client // this could be pretty much everything that binds to an event loop $browser = new React\Http\Browser(); // set up two parallel requests $request1 = $browser->get('http://www.google.com/'); $request2 = $browser->get('http://www.google.co.uk/'); // keep the loop running (i.e. block) until the first response arrives $fasterResponse = Clue\React\Block\awaitAny(array($request1, $request2)); return $fasterResponse->getBody(); }
用法
这个轻量级库仅包含几个简单的函数。所有函数都位于Clue\React\Block
命名空间下。
以下示例展示了所有函数的完整限定名称,例如这样:
Clue\React\Block\await(…);
从PHP 5.6+版本开始,您也可以将每个所需的函数导入到代码中,如下所示:
use function Clue\React\Block\await; await(…);
或者,您也可以使用类似的导入语句:
use Clue\React\Block; Block\await(…);
sleep()
sleep(float $seconds, ?LoopInterface $loop = null): void
函数可以用来等待/sleep指定的时间$time
秒。
Clue\React\Block\sleep(1.5, $loop);
此函数将在指定的$time
时间过后才返回。在此期间,事件循环将运行与同一循环相关联的其他事件,直到计时器触发。如果没有其他事件附加到该循环,则其行为将与内置的sleep()
函数相似。
在内部,将使用$time
参数作为循环的计时器,使其在计时器触发前持续运行。这意味着如果您传递一个非常小(或负数)的值,它仍然会启动计时器,因此会在未来可能最早的时间触发。
此函数接受一个可选的LoopInterface|null $loop
参数,可以用来传递要使用的事件循环实例。您可以使用null
值,以使用默认循环。除非您确定要显式使用特定的事件循环实例,否则不应提供此值。
请注意,此函数将控制事件循环。在内部,它将实际运行
循环,直到计时器触发,然后调用stop()
来终止循环的执行。这意味着此函数更适合于使用异步API不可行的短期程序执行。对于长运行的应用程序,通常更喜欢通过定时器利用事件驱动API。
await()
await(PromiseInterface $promise, ?LoopInterface $loop = null, ?float $timeout = null): mixed
函数可以用来阻塞等待指定的$promise
得到解决。
$result = Clue\React\Block\await($promise);
此函数将在指定的$promise
得到解决后(即满足或拒绝)才返回。在此期间,事件循环将运行与同一循环相关联的其他事件,直到承诺解决。
一旦承诺得到解决,此函数将返回承诺解决的任何内容。
一旦承诺被拒绝,此函数将抛出承诺拒绝的内容。如果承诺没有用Exception
拒绝,则此函数将抛出UnexpectedValueException
。
try { $result = Clue\React\Block\await($promise); // promise successfully fulfilled with $result echo 'Result: ' . $result; } catch (Exception $exception) { // promise rejected with $exception echo 'ERROR: ' . $exception->getMessage(); }
有关示例,请参阅示例。
此函数接受一个可选的LoopInterface|null $loop
参数,可以用来传递要使用的事件循环实例。您可以使用null
值,以使用默认循环。除非您确定要显式使用特定的事件循环实例,否则不应提供此值。
如果没有提供$timeout
参数,并且承诺保持挂起状态,那么它可能会无限期地等待/阻塞,直到承诺得到解决。为了避免这种情况,创建承诺的API作者应提供一种方法来配置承诺的超时。有关更多详细信息,请参阅timeout()
函数。
如果提供了已弃用的$timeout
参数,并且承诺在超时触发时仍然挂起,那么它将取消
承诺并抛出TimeoutException
。这意味着如果您传递一个非常小(或负数)的值,它仍然会启动计时器,因此会在未来可能最早的时间触发。
请注意,此函数将控制事件循环。内部实际上会通过调用 run()
来运行循环,直到承诺解决,然后调用 stop()
来终止循环的执行。这意味着此函数更适合在无法使用基于承诺的 API 的情况下执行短暂的承诺。对于长期运行的应用程序,通常更倾向于通过链式调用 then()
来使用基于承诺的 API。
awaitAny()
awaitAny(PromiseInterface[] $promises, ?LoopInterface $loop = null, ?float $timeout = null): mixed
函数可以用来等待给定的承诺中的任何一个被解决。
$promises = array( $promise1, $promise2 ); $firstResult = Clue\React\Block\awaitAny($promises); echo 'First result: ' . $firstResult;
有关示例,请参阅示例。
此函数仅在给定的 $promises
中的任何一个被解决后才会返回,或者当所有承诺都被拒绝时会抛出异常。在此期间,事件循环将运行同一循环上附加的所有事件。
一旦任何一个承诺被解决,此函数将返回该承诺解决的值,并尝试取消所有剩余的承诺。
一旦所有承诺都被拒绝,此函数将失败并抛出 UnderflowException
。同样,如果传递了一个空的 $promises
数组,它也会抛出。
此函数接受一个可选的LoopInterface|null $loop
参数,可以用来传递要使用的事件循环实例。您可以使用null
值,以使用默认循环。除非您确定要显式使用特定的事件循环实例,否则不应提供此值。
如果没有提供 $timeout
参数,并且所有承诺都保持挂起状态,那么这可能会无限期地等待/阻塞,直到承诺被解决。为了避免这种情况,创建承诺的 API 作者应提供配置承诺超时的方法。有关更多详细信息,请参阅timeout()
函数。
如果提供了已弃用的 $timeout
参数,并且超时触发时任何承诺仍然挂起,这将取消所有挂起的承诺并抛出 TimeoutException
。这意味着如果您传递一个非常小(或负数)的值,它仍然会启动计时器,因此会在将来最早可能的时间触发。
请注意,此函数将控制事件循环。内部实际上会通过调用 run()
来运行循环,直到承诺解决,然后调用 stop()
来终止循环的执行。这意味着此函数更适合在无法使用基于承诺的 API 的情况下执行短暂的承诺。对于长期运行的应用程序,通常更倾向于通过链式调用 then()
来使用基于承诺的 API。
awaitAll()
awaitAll(PromiseInterface[] $promises, ?LoopInterface $loop = null, ?float $timeout = null): mixed[]
函数可以用来等待给定的所有承诺被解决。
$promises = array( $promise1, $promise2 ); $allResults = Clue\React\Block\awaitAll($promises); echo 'First promise resolved with: ' . $allResults[0];
有关示例,请参阅示例。
此函数仅在给定的所有 $promises
都被解决后才会返回,或者当任何一个被拒绝时抛出异常。在此期间,事件循环将运行同一循环上附加的所有事件。
一旦所有承诺都得到解决,这将返回一个数组,其中包含每个承诺解决的值。数组键将保持不变,即可以使用它们将返回数组与传入的承诺相关联。同样,如果传递了一个空的 $promises
数组,它将返回一个空数组。
一旦任何一个承诺被拒绝,这将尝试取消所有剩余的承诺并抛出 Exception
。如果承诺没有用 Exception
拒绝,则此函数将抛出 UnexpectedValueException
。
此函数接受一个可选的LoopInterface|null $loop
参数,可以用来传递要使用的事件循环实例。您可以使用null
值,以使用默认循环。除非您确定要显式使用特定的事件循环实例,否则不应提供此值。
如果没有提供 $timeout
参数,并且任何一个承诺保持挂起状态,那么这可能会无限期地等待/阻塞,直到承诺被解决。为了避免这种情况,创建承诺的 API 作者应提供配置承诺超时的方法。有关更多详细信息,请参阅timeout()
函数。
如果提供了已弃用的 $timeout
参数,并且超时触发时任何承诺仍然挂起,这将取消所有挂起的承诺并抛出 TimeoutException
。这意味着如果您传递一个非常小(或负数)的值,它仍然会启动计时器,因此会在将来最早可能的时间触发。
请注意,此函数将控制事件循环。内部实际上会通过调用 run()
来运行循环,直到承诺解决,然后调用 stop()
来终止循环的执行。这意味着此函数更适合在无法使用基于承诺的 API 的情况下执行短暂的承诺。对于长期运行的应用程序,通常更倾向于通过链式调用 then()
来使用基于承诺的 API。
安装
推荐通过 Composer 安装此库。 初识 Composer?
此项目遵循 SemVer。这将安装最新的支持版本。
$ composer require clue/block-react:^1.5
另请参阅CHANGELOG,了解版本升级的详细信息。
此项目旨在在所有平台上运行,因此不要求安装任何PHP扩展,并支持在旧版PHP 5.3到当前PHP 8+和HHVM上运行。强烈建议使用此项目的最新支持的PHP版本。
测试
要运行测试套件,您首先需要克隆此仓库,然后通过Composer安装所有依赖项(Composer)
$ composer install
要运行测试套件,请转到项目根目录并运行
$ vendor/bin/phpunit
许可
此项目以宽松的MIT许可发布。
你知道吗?我提供定制开发服务,并为发布赞助和贡献开具发票。如需详细信息,请联系我(@clue)。