clue/promise-timeout

此包已被弃用且不再维护。作者建议使用 react/promise-timer 包代替。

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

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

This package is auto-updated.

Last update: 2024-06-04 14:29:53 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();

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

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

$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()等。

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

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上运行。强烈建议使用此项目的最新支持版本。

测试

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

composer install

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

vendor/bin/phpunit

许可证

麻省理工学院,参见 许可证文件