react/promise-timer

基于 ReactPHP 的简单 Promise 超时实现。

资助包维护!
Open Collective

安装数: 28,908,614

依赖者: 78

建议者: 1

安全: 0

星星: 337

监视者: 10

分支: 17

开放问题: 1

v1.11.0 2024-06-04 14:27 UTC

This package is auto-updated.

Last update: 2024-09-04 14:59:39 UTC


README

CI status installs on Packagist

基于 ReactPHP 的简单 Promise 超时实现。

目录

用法

这个轻量级库仅包含几个简单的函数。所有函数都位于 React\Promise\Timer 命名空间下。

以下示例使用以下方式引用所有函数的完全限定名称

React\Promise\Timer\timeout(…);

从 PHP 5.6+ 开始,您也可以像这样将每个所需的函数导入到代码中

use function React\Promise\Timer\timeout;

timeout(…);

或者,您也可以使用类似的导入语句

use React\Promise\Timer;

Timer\timeout(…);

timeout()

timeout(PromiseInterface<T> $promise, float $time, ?LoopInterface $loop = null): PromiseInterface<T> 函数可用于取消耗时过长的操作。

您需要传入一个表示挂起操作的 $promise 输入和一个超时参数。它返回一个新的具有以下解决行为的 promise

  • 如果输入的 $promise$time 秒内解决,则使用其完成值解决相应的 promise。

  • 如果输入的 $promise$time 秒内拒绝,则使用其拒绝值拒绝相应的 promise。

  • 如果输入的 $promise$time 秒内没有解决,则 取消 操作并使用一个 TimeoutException 拒绝相应的 promise。

内部,给定的 $time 值将用于启动一个计时器,该计时器将在触发时 取消 挂起操作。这意味着如果您传入一个非常小(或负数)的值,它仍然会启动一个计时器,因此它将在未来的最早可能时间触发。

如果输入的 $promise 已经解决,则相应的 promise 将立即解决或拒绝,而不会启动任何计时器。

此函数接受一个可选的 LoopInterface|null $loop 参数,可用于传入要使用的事件循环实例。您可以使用一个 null 值来使用默认循环。除非您确定您想要显式使用给定的事件循环实例,否则不应提供此值。

处理仅解决值的常见用例如下

$promise = accessSomeRemoteResource();
React\Promise\Timer\timeout($promise, 10.0)->then(function ($value) {
    // the operation finished within 10.0 seconds
});

更完整的示例可能如下所示

$promise = accessSomeRemoteResource();
React\Promise\Timer\timeout($promise, 10.0)->then(
    function ($value) {
        // the operation finished within 10.0 seconds
    },
    function ($error) {
        if ($error instanceof React\Promise\Timer\TimeoutException) {
            // the operation has failed due to a timeout
        } else {
            // the input operation has failed due to some other error
        }
    }
);

或者如果您正在使用 react/promise v3

React\Promise\Timer\timeout($promise, 10.0)->then(function ($value) {
    // the operation finished within 10.0 seconds
})->catch(function (React\Promise\Timer\TimeoutException $error) {
    // the operation has failed due to a timeout
})->catch(function (Throwable $error) {
    // the input operation has failed due to some other error
});

如上所述,timeout() 函数将处理底层操作,如果它耗时过长。在这种情况下,您可以确信结果 promise 将始终使用一个 TimeoutException 被拒绝。在此之上,该函数将尝试 取消 底层操作。此取消逻辑的责任留给底层操作。

  • 常见的使用场景包括清理任何资源,如打开的网络套接字、文件句柄、终止外部进程或计时器。

  • 如果给定的输入 $promise 不支持取消,则此操作为无操作(NO-OP)。这意味着虽然结果承诺仍然会被拒绝,但底层的输入 $promise 可能仍然处于挂起状态,因此可以继续消耗资源

此外,返回的承诺是以一种可以在挂起时取消的方式实现的。取消挂起的承诺将取消底层操作。如上所述,取消逻辑的责任留给了底层操作。

$promise = accessSomeRemoteResource();
$timeout = React\Promise\Timer\timeout($promise, 10.0);

$timeout->cancel();

有关承诺取消的更多详细信息,请参阅Promise 文档

如果您想等待多个承诺解析,您可以使用这样的正常承诺原语

$promises = array(
    accessSomeRemoteResource(),
    accessSomeRemoteResource(),
    accessSomeRemoteResource()
);

$promise = React\Promise\all($promises);

React\Promise\Timer\timeout($promise, 10)->then(function ($values) {
    // *all* promises resolved
});

这适用于所有承诺集合原语,例如 all()race()any()some() 等。

有关承诺原语的更多详细信息,请参阅Promise 文档

sleep()

sleep(float $time, ?LoopInterface $loop = null): PromiseInterface<void> 函数可用于创建在 $time 秒后解析的新承诺。

React\Promise\Timer\sleep(1.5)->then(function () {
    echo 'Thanks for waiting!' . PHP_EOL;
});

内部,给定的 $time 值将用于启动一个计时器,一旦触发,它就会解析承诺。这意味着如果您传递一个非常小(或负数)的值,它仍然会启动一个计时器,因此将在未来最早可能的时间触发。

此函数接受一个可选的 LoopInterface|null $loop 参数,可用于传入要使用的事件循环实例。您可以使用一个 null 值来使用默认循环。除非您确定您想要显式使用给定的事件循环实例,否则不应提供此值。

返回的承诺是以一种可以在挂起时取消的方式实现的。取消挂起的承诺将以 RuntimeException 拒绝其值并清理任何挂起的计时器。

$timer = React\Promise\Timer\sleep(2.0);

$timer->cancel();

resolve()

自 v1.8.0 版本以来已弃用,请参阅sleep()

resolve(float $time, ?LoopInterface $loop = null): PromiseInterface<float> 函数可用于创建在 $time 秒后解析的新承诺,其中 $time 作为实现值。

React\Promise\Timer\resolve(1.5)->then(function ($time) {
    echo 'Thanks for waiting ' . $time . ' seconds' . PHP_EOL;
});

内部,给定的 $time 值将用于启动一个计时器,一旦触发,它就会解析承诺。这意味着如果您传递一个非常小(或负数)的值,它仍然会启动一个计时器,因此将在未来最早可能的时间触发。

此函数接受一个可选的 LoopInterface|null $loop 参数,可用于传入要使用的事件循环实例。您可以使用一个 null 值来使用默认循环。除非您确定您想要显式使用给定的事件循环实例,否则不应提供此值。

返回的承诺是以一种可以在挂起时取消的方式实现的。取消挂起的承诺将以 RuntimeException 拒绝其值并清理任何挂起的计时器。

$timer = React\Promise\Timer\resolve(2.0);

$timer->cancel();

reject()

自 v1.8.0 版本以来已弃用,请参阅sleep()

reject(float $time, ?LoopInterface $loop = null): PromiseInterface<never> 函数可用于创建在 $time 秒后拒绝的承诺,使用 TimeoutException

React\Promise\Timer\reject(2.0)->then(null, function (React\Promise\Timer\TimeoutException $e) {
    echo 'Rejected after ' . $e->getTimeout() . ' seconds ' . PHP_EOL;
});

内部,给定的 $time 值将用于启动一个计时器,一旦触发,它就会拒绝承诺。这意味着如果您传递一个非常小(或负数)的值,它仍然会启动一个计时器,因此将在未来最早可能的时间触发。

此函数接受一个可选的 LoopInterface|null $loop 参数,可用于传入要使用的事件循环实例。您可以使用一个 null 值来使用默认循环。除非您确定您想要显式使用给定的事件循环实例,否则不应提供此值。

返回的承诺是以一种可以在挂起时取消的方式实现的。取消挂起的承诺将以 RuntimeException 拒绝其值并清理任何挂起的计时器。

$timer = React\Promise\Timer\reject(2.0);

$timer->cancel();

TimeoutException

TimeoutException 扩展 PHP 的内置 RuntimeException

getTimeout()

getTimeout(): float 方法可用于获取以秒为单位的超时值。

安装

建议使用Composer 安装此库。 对 Composer 不熟悉?

此项目遵循SemVer。这将安装最新支持的版本

composer require react/promise-timer:^1.11

有关版本升级的详细信息,请参阅变更日志

此项目旨在在任何平台上运行,因此不需要任何 PHP 扩展,并支持在旧版 PHP 5.3 到当前 PHP 8+ 和 HHVM 上运行。强烈建议使用此项目的最新支持 PHP 版本。

测试

要运行测试套件,您首先需要克隆此存储库,然后通过Composer 安装所有依赖项

composer install

要运行测试套件,请转到项目根目录并运行

vendor/bin/phpunit

许可

MIT,请参阅许可证文件