|  Download PromiseTimer
 A trivial implementation of timeouts for Promises, built on top of ReactPHP. Table of contents UsageThis lightweight library consists only of a few simple functions.
All functions reside under the React\Promise\Timernamespace. The below examples assume you use an import statement similar to this: use React\Promise\Timer;
Timer\timeout(?);
 Alternatively, you can also refer to them with their fully-qualified name: \React\Promise\Timer\timeout(?);
 timeout()The timeout(PromiseInterface $promise, $time, LoopInterface $loop)function
can be used to cancel operations that take too long.
You need to pass in an input$promisethat represents a pending operation and timeout parameters.
It returns a newPromisewith the following resolution behavior: 
If the input `$promise` resolves before `$time` seconds, resolve the resulting promise with its fulfillment value.
If the input `$promise` rejects before `$time` seconds, reject the resulting promise with its rejection value.
If the input `$promise` does not settle before `$time` seconds, cancel the operation and reject the resulting promise with a TimeoutException.
 Internally, the given $timevalue will be used to start a timer that will
cancel the pending operation once it triggers.
This implies that if you pass a really small (or negative) value, it will still
start a timer and will thus trigger at the earliest possible time in the future. If the input $promiseis already settled, then the resulting promise will
resolve or reject immediately without starting a timer at all. A common use case for handling only resolved values looks like this: $promise = accessSomeRemoteResource();
Timer\timeout($promise, 10.0, $loop)->then(function ($value) {
    // the operation finished within 10.0 seconds
});
 A more complete example could look like this: $promise = accessSomeRemoteResource();
Timer\timeout($promise, 10.0, $loop)->then(
    function ($value) {
        // the operation finished within 10.0 seconds
    },
    function ($error) {
        if ($error instanceof Timer\TimeoutException) {
            // the operation has failed due to a timeout
        } else {
            // the input operation has failed due to some other error
        }
    }
);
 Or if you're using react/promise v2.2.0 or up: Timer\timeout($promise, 10.0, $loop)
    ->then(function ($value) {
        // the operation finished within 10.0 seconds
    })
    ->otherwise(function (Timer\TimeoutException $error) {
        // the operation has failed due to a timeout
    })
    ->otherwise(function ($error) {
        // the input operation has failed due to some other error
    })
;
 Timeout cancellationAs discussed above, the timeout()function will cancel the
underlying operation if it takes too long.
This means that you can be sure the resulting promise will then be rejected
with aTimeoutException. However, what happens to the underlying input $promiseis a bit more tricky:
Once the timer fires, we will try to call$promise->cancel()on the input$promisewhich in turn invokes its cancellation handler. This means that it's actually up the input $promiseto handle
cancellation support. 
A common use case involves cleaning up any resources like open network sockets or
file handles or terminating external processes or timers.
If the given input `$promise` does not support cancellation, then this is a NO-OP.
This means that while the resulting promise will still be rejected, the underlying
input `$promise` may still be pending and can hence continue consuming resources.
 See the following chapter for more details on the cancellation handler. Cancellation handlerFor example, an implementation for the above operation could look like this: function accessSomeRemoteResource()
{
    return new Promise(
        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(new \RuntimeException('Operation cancelled'));
        }
    );
}
 In this example, calling $promise->cancel()will invoke the registered cancellation
handler which then closes the network socket and rejects thePromiseinstance. If no cancellation handler is passed to the Promiseconstructor, then invoking
itscancel()method it is effectively a NO-OP.
This means that it may still be pending and can hence continue consuming resources. For more details on the promise cancellation, please refer to the
Promise documentation. Input cancellationIrrespective of the timeout handling, you can also explicitly cancel()the
input$promiseat any time.
This means that thetimeout()handling does not affect cancellation of the
input$promise, as demonstrated in the following example: $promise = accessSomeRemoteResource();
$timeout = Timer\timeout($promise, 10.0, $loop);
$promise->cancel();
 The registered cancellation handler is responsible for
handling the cancel()call: 
A described above, a common use involves resource cleanup and will then reject
the `Promise`.
If the input `$promise` is being rejected, then the timeout will be aborted
and the resulting promise will also be rejected.
If the input `$promise` is still pending, then the timout will continue
running until the timer expires.
The same happens if the input `$promise` does not register a
cancellation handler. 
 Output cancellationSimilarily, you can also explicitly cancel()the resulting promise like this: $promise = accessSomeRemoteResource();
$timeout = Timer\timeout($promise, 10.0, $loop);
$timeout->cancel();
 Note how this looks very similar to the above input cancellation
example. Accordingly, it also behaves very similar. Calling cancel()on the resulting promise will merely try
tocancel()the input$promise.
This means that we do not take over responsibility of the outcome and it's
entirely up to the input$promiseto handle cancellation support. The registered cancellation handler is responsible for
handling the cancel()call: 
As described above, a common use involves resource cleanup and will then reject
the `Promise`.
If the input `$promise` is being rejected, then the timeout will be aborted
and the resulting promise will also be rejected.
If the input `$promise` is still pending, then the timout will continue
running until the timer expires.
The same happens if the input `$promise` does not register a
cancellation handler. 
 To re-iterate, note that calling cancel()on the resulting promise will merely
try to cancel the input$promiseonly.
It is then up to the cancellation handler of the input promise to settle the promise.
If the input promise is still pending when the timeout occurs, then the normal
timeout cancellation handling will trigger, effectively rejecting
the output promise with aTimeoutException. This is done for consistency with the timeout cancellation
handling and also because it is assumed this is often used like this: $timeout = Timer\timeout(accessSomeRemoteResource(), 10.0, $loop);
$timeout->cancel();
 As described above, this example works as expected and cleans up any resources
allocated for the input $promise. Note that if the given input $promisedoes not support cancellation, then this
is a NO-OP.
This means that while the resulting promise will still be rejected after the
timeout, the underlying input$promisemay still be pending and can hence
continue consuming resources. CollectionsIf you want to wait for multiple promises to resolve, you can use the normal promise primitives like this: $promises = array(
    accessSomeRemoteResource(),
    accessSomeRemoteResource(),
    accessSomeRemoteResource()
);
$promise = \React\Promise\all($promises);
Timer\timeout($promise, 10, $loop)->then(function ($values) {
    // all promises resolved
});
 The applies to all promise collection primitives alike, i.e. all(),race(),any(),some()etc. For more details on the promise primitives, please refer to the
Promise documentation. resolve()The resolve($time, LoopInterface $loop)function can be used to create a new Promise that
resolves in$timeseconds with the$timeas the fulfillment value. Timer\resolve(1.5, $loop)->then(function ($time) {
    echo 'Thanks for waiting ' . $time . ' seconds' . PHP_EOL;
});
 Internally, the given $timevalue will be used to start a timer that will
resolve the promise once it triggers.
This implies that if you pass a really small (or negative) value, it will still
start a timer and will thus trigger at the earliest possible time in the future. Resolve cancellationYou can explicitly cancel()the resulting timer promise at any time: $timer = Timer\resolve(2.0, $loop);
$timer->cancel();
 This will abort the timer and reject with a RuntimeException. reject()The reject($time, LoopInterface $loop)function can be used to create a new Promise
which rejects in$timeseconds with aTimeoutException. Timer\reject(2.0, $loop)->then(null, function (TimeoutException $e) {
    echo 'Rejected after ' . $e->getTimeout() . ' seconds ' . PHP_EOL;
});
 Internally, the given $timevalue will be used to start a timer that will
reject the promise once it triggers.
This implies that if you pass a really small (or negative) value, it will still
start a timer and will thus trigger at the earliest possible time in the future. This function complements the resolve()function
and can be used as a basic building block for higher-level promise consumers. Reject cancellationYou can explicitly cancel()the resulting timer promise at any time: $timer = Timer\reject(2.0, $loop);
$timer->cancel();
 This will abort the timer and reject with a RuntimeException. TimeoutExceptionThe TimeoutExceptionextends PHP's built-inRuntimeException. The getTimeout()method can be used to get the timeout value in seconds. InstallThe recommended way to install this library is through Composer.
New to Composer? This project follows SemVer.
This will install the latest supported version: $ composer require react/promise-timer:^1.5
 See also the CHANGELOG for details about version upgrades. This project aims to run on any platform and thus does not require any PHP
extensions and supports running on legacy PHP 5.3 through current PHP 7+ and
HHVM.
It's highly recommended to use PHP 7+ for this project. TestsTo run the test suite, you first need to clone this repo and then install all
dependencies through Composer: $ composer install
 To run the test suite, go to the project root and run: $ php vendor/bin/phpunit
 LicenseMIT, see LICENSE file. |