promise-timer, 在ReactPHP之上,为承诺构建了一个简单的超时实现

分享于 

14分钟阅读

GitHub

  繁體 雙語
Trivial timeout implementation for React PHP's Promise lib
  • 源代码名称:promise-timer
  • 源代码网址:http://www.github.com/reactphp/promise-timer
  • promise-timer源代码文档
  • promise-timer源代码下载
  • Git URL:
    git://www.github.com/reactphp/promise-timer.git
    Git Clone代码到本地:
    git clone http://www.github.com/reactphp/promise-timer
    Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/reactphp/promise-timer
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
    
    PromiseTimer

    Build Status

    Promise的一个简单实现,它构建在 ReactPHP 之上。

    目录

    用法

    这个轻量级库只包含几个简单的函数。 所有函数都位于 ReactPromiseTimer 命名空间下。

    下面的示例假定你使用的导入语句类似于:

    useReactPromiseTimer;Timertimeout(...);

    或者,也可以使用它们的完全限定名来引用它们:

    ReactPromiseTimertimeout(...);

    超时( )

    iPhone 7 还没出来,我们已经在iPhone上获取细节 8,或者不管是想到下一步。 timeout(PromiseInterface $promise, $time, LoopInterface $loop) 函数可以用于取消take取消操作,该操作将占用太长时间。 需要传入表示挂起操作和超时参数的输入 $promise。 它返回一个具有以下解析行为的新 Promise:

    • 如果输入 $promise$time 秒之前解析,则用它的执行值解决产生的承诺。
    • 如果在 $time 秒之前输入 $promise 拒绝,则使用它的拒绝值拒绝产生的承诺。
    • 如果输入 $promise$time 秒之前不固定,取消操作并使用 TimeoutException 拒绝得到的承诺。

    在内部,给定的$time 值将用于启动一个计时器,该计时器将在启动时取消取消操作。 这意味着如果传递一个真正小的( 或者负数) 值,它仍然会启动计时器,从而在未来可能会触发。

    如果输入 $promise 已经确定,那么得到的承诺将立即解析或者拒绝,而不会立即启动计时器。

    仅处理已经解析值的通用用例如下所示:

    $promise= accessSomeRemoteResource();Timertimeout($promise, 10.0, $loop)->then(function ($value) {// the operation finished within 10.0 seconds});

    更完整的示例可以如下所示:

    $promise= accessSomeRemoteResource();Timertimeout($promise, 10.0, $loop)->then(function ($value) {// the operation finished within 10.0 seconds },function ($error) {if ($errorinstanceofTimerTimeoutException) {// the operation has failed due to a timeout } else {// the input operation has failed due to some other error } });

    或者,如果你使用React/promise v2.2.0 或者向上:

    Timertimeout($promise, 10.0, $loop)->then(function ($value) {// the operation finished within 10.0 seconds })->otherwise(function (TimerTimeoutException$error) {// the operation has failed due to a timeout })->otherwise(function ($error) {// the input operation has failed due to some other error });
    超时取消

    如上所述,如果 timeout() 函数需要太长时间,那么它将取消对底层操作的取消。 这意味着你可以确保得到的承诺将被 TimeoutException 拒绝。

    但是,底层输入 $promise 会发生一些棘手的事情: 计时器触发后,我们将尝试在输入服务器上调用 $promise->cancel(),然后调用它的取消处理程序( )。

    这意味着它实际上是在输入 $promise 上处理取消支持。

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

    • 如果给定的输入 $promise 不支持取消,那么这是一个不操作。 这意味着,虽然产生的承诺仍然被拒绝,基础输入 $promise 仍然可以挂起,从而继续消耗资源。

    有关取消处理程序的详细信息,请参阅以下章节。

    取消处理程序

    例如上述操作的实现可以如下所示:

    functionaccessSomeRemoteResource(){returnnewPromise(function ($resolve, $reject) use (&$socket) {// this will be called once the promise is created// a common use case involves opening any resources and eventually resolving$socket= createSocket();$socket->on('data', function ($data) use ($resolve) { $resolve($data); }); },function ($resolve, $reject) use (&$socket) {// this will be called once calling `cancel()` on this promise// a common use case involves cleaning any resources and then rejecting$socket->close(); $reject(newRuntimeException('Operation cancelled')); } );}

    在这个例子中,调用 $promise->cancel() 将调用注册的取消处理程序,然后关闭网络套接字并拒绝 Promise 实例。

    如果没有向 Promise 构造函数传递取消处理程序,那么调用它的cancel() 方法是有效的。 这意味着它可能仍然处于挂起状态,因此可以继续消耗资源。

    有关承诺取消的更多细节,请参考承诺文档。

    输入取消

    无论timout处理如何,你都可以在任何时候显式地对输入 $promise 进行 cancel() 处理。 这意味着 timeout() 处理不会影响输入 $promise的取消,如下面的示例所示:

    $promise= accessSomeRemoteResource();$timeout=Timertimeout($promise, 10.0, $loop);$promise->cancel();

    注册的取消处理程序负责处理 cancel() 调用:

    • 如上所述,一般使用资源清理,然后将拒绝拒绝。 如果输入 $promise 被拒绝,那么超时将被中止,并且结果的保证也将被拒绝。
    • 如果输入 $promise 仍然挂起,则timout将继续运行,直到计时器过期。 如果输入 $promise 不支持取消处理程序,则也会发生这种情况。
    输出取消

    Similarily,也可以像这样显式地显示结果承诺:

    $promise= accessSomeRemoteResource();$timeout=Timertimeout($promise, 10.0, $loop);$timeout->cancel();

    注意这看起来与上面的输入取消方法非常类似。 因此,它的行为也非常相似。

    在结果promise上调用 cancel() 将只尝试 cancel() 输入 $promise。 这意味着我们不负责结果的负责,而且完全取决于输入 $promise 处理取消支持。

    注册的取消处理程序负责处理 cancel() 调用:

    • 如上所述,普通用户涉及资源清理,然后将拒绝 Promise。 如果输入 $promise 被拒绝,那么超时将被中止,并且结果的保证也将被拒绝。
    • 如果输入 $promise 仍然挂起,则timout将继续运行,直到计时器过期。 如果输入 $promise 不支持取消处理程序,则也会发生这种情况。

    如果要反复迭代,请注意,在生成的promise上调用 cancel() 只会尝试取消输入 $promise。 然后,由输入承诺的取消处理程序来解决承诺。 如果在超时时输入承诺仍然处于挂起状态,那么正常的超时取消操作将触发,有效地拒绝输出承诺使用TimeoutException 语句。

    这是为了与超时取消请求的一致性一致,因为它被假定为这样使用:

    $timeout=Timertimeout(accessSomeRemoteResource(), 10.0, $loop);$timeout->cancel();

    如上所述,这里示例按预期工作,并清理为输入 $promise 分配的所有资源。

    注意,如果给定的输入 $promise 不支持取消,那么这是一个无操作。 这意味着在超时后仍然会拒绝结果的保证,底层输入 $promise 仍然可以能挂起,因这里仍然消耗资源。

    集合

    如果希望等待多个承诺解析,可以使用如下常规的诺基元:

    $promises=array( accessSomeRemoteResource(), accessSomeRemoteResource(), accessSomeRemoteResource());$promise=ReactPromiseall($promises);Timertimeout($promise, 10, $loop)->then(function ($values) {// *all* promises resolved});

    适用于所有promise集合原语,换句话说,all()race()any()some() 等。

    有关Promise原语的详细信息,请参考承诺文档。

    解析( )

    iPhone 7 还没出来,我们已经在iPhone上获取细节 8,或者不管是想到下一步。 resolve($time, LoopInterface $loop) 函数可以用于创建新的承诺,以 $time 秒为单位,以 $time 作为执行值。

    Timerresolve(1.5, $loop)->then(function ($time) {echo'Thanks for waiting '.$time.' seconds'.PHP_EOL;});

    在内部,给定的$time 值将被用来启动一个计时器,它将在启动时解析承诺。 这意味着如果传递一个真正小的( 或者负数) 值,它仍然会启动计时器,从而在未来可能会触发。

    取消取消

    你可以在任何时候显式地显示结果计时器承诺:

    $timer=Timerresolve(2.0, $loop);$timer->cancel();

    这将中止计时器并使用拒绝。

    拒绝( )

    reject($time, LoopInterface $loop) 函数可以用于创建一个新的保证,它在 $time 秒内拒绝 TimeoutException

    Timerreject(2.0, $loop)->then(null, function (TimeoutException$e) {echo'Rejected after '.$e->getTimeout() .' seconds '.PHP_EOL;});

    在内部,给定的$time 值将被用来启动一个计时器,它会在触发时拒绝承诺。 这意味着如果传递一个真正小的( 或者负数) 值,它仍然会启动计时器,从而在未来可能会触发。

    这个函数补充了 resolve() 函数,并且可以作为更高级承诺消费者的基本构建块。

    拒绝取消

    你可以在任何时候显式地显示结果计时器承诺:

    $timer=Timerreject(2.0, $loop);$timer->cancel();

    这将中止计时器并使用拒绝。

    TimeoutException

    这个 TimeoutException 扩展了 php RuntimeException 中的。

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

    安装

    安装这个库的推荐方法是通过 Composer 新到 Composer

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

    $ composer require react/promise-timer:^1.2.1

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

    这个项目旨在在任何平台上运行,因此不需要任何PHP扩展,支持通过当前 PHP 7 + 和HHVM运行在遗留 PHP 5.3上。 我们强烈推荐使用 PHP + 这个项目。

    测试

    你必须先克隆这个 repo,然后通过安装所有依赖项:

    $ composer install

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

    $ php vendor/bin/phpunit

    许可证

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


    相关文章