{"id":18941222,"url":"https://github.com/reactphp/promise-timer","last_synced_at":"2025-05-15T15:01:46.432Z","repository":{"id":34407466,"uuid":"38336521","full_name":"reactphp/promise-timer","owner":"reactphp","description":"A trivial implementation of timeouts for Promises, built on top of ReactPHP.","archived":false,"fork":false,"pushed_at":"2025-03-28T09:55:02.000Z","size":115,"stargazers_count":337,"open_issues_count":1,"forks_count":17,"subscribers_count":11,"default_branch":"1.x","last_synced_at":"2025-05-05T07:21:30.668Z","etag":null,"topics":["php","promise","reactphp","timer"],"latest_commit_sha":null,"homepage":"https://reactphp.org/promise-timer/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/reactphp.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["reactphp","clue","WyriHaximus"],"open_collective":"reactphp"}},"created_at":"2015-06-30T22:33:37.000Z","updated_at":"2025-04-01T06:29:02.000Z","dependencies_parsed_at":"2023-12-27T11:14:38.876Z","dependency_job_id":"5945aa97-347e-4274-a863-7b668d6036e2","html_url":"https://github.com/reactphp/promise-timer","commit_stats":{"total_commits":82,"total_committers":10,"mean_commits":8.2,"dds":0.5487804878048781,"last_synced_commit":"625f497009f14a695fd90ef9fc946537971ff4ce"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactphp%2Fpromise-timer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactphp%2Fpromise-timer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactphp%2Fpromise-timer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactphp%2Fpromise-timer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/reactphp","download_url":"https://codeload.github.com/reactphp/promise-timer/tar.gz/refs/heads/1.x","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254057530,"owners_count":22007544,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["php","promise","reactphp","timer"],"created_at":"2024-11-08T12:26:45.826Z","updated_at":"2025-05-15T15:01:46.181Z","avatar_url":"https://github.com/reactphp.png","language":"PHP","funding_links":["https://github.com/sponsors/reactphp","https://github.com/sponsors/clue","https://github.com/sponsors/WyriHaximus","https://opencollective.com/reactphp"],"categories":[],"sub_categories":[],"readme":"# PromiseTimer\n\n[![CI status](https://github.com/reactphp/promise-timer/actions/workflows/ci.yml/badge.svg)](https://github.com/reactphp/promise-timer/actions)\n[![installs on Packagist](https://img.shields.io/packagist/dt/react/promise-timer?color=blue\u0026label=installs%20on%20Packagist)](https://packagist.org/packages/react/promise-timer)\n\nA trivial implementation of timeouts for `Promise`s, built on top of [ReactPHP](https://reactphp.org/).\n\n**Table of contents**\n\n* [Usage](#usage)\n    * [timeout()](#timeout)\n    * [sleep()](#sleep)\n    * [~~resolve()~~](#resolve)\n    * [~~reject()~~](#reject)\n    * [TimeoutException](#timeoutexception)\n        * [getTimeout()](#gettimeout)\n* [Install](#install)\n* [Tests](#tests)\n* [License](#license)\n\n## Usage\n\nThis lightweight library consists only of a few simple functions.\nAll functions reside under the `React\\Promise\\Timer` namespace.\n\nThe below examples refer to all functions with their fully-qualified names like this:\n\n```php\nReact\\Promise\\Timer\\timeout(…);\n```\n\nAs of PHP 5.6+ you can also import each required function into your code like this:\n\n```php\nuse function React\\Promise\\Timer\\timeout;\n\ntimeout(…);\n```\n\nAlternatively, you can also use an import statement similar to this:\n\n```php\nuse React\\Promise\\Timer;\n\nTimer\\timeout(…);\n```\n\n### timeout()\n\nThe `timeout(PromiseInterface\u003cT\u003e $promise, float $time, ?LoopInterface $loop = null): PromiseInterface\u003cT\u003e` function can be used to\ncancel operations that take *too long*.\n\nYou need to pass in an input `$promise` that represents a pending operation\nand timeout parameters. It returns a new promise with the following\nresolution behavior:\n\n- If the input `$promise` resolves before `$time` seconds, resolve the\n  resulting promise with its fulfillment value.\n\n- If the input `$promise` rejects before `$time` seconds, reject the\n  resulting promise with its rejection value.\n\n- If the input `$promise` does not settle before `$time` seconds, *cancel*\n  the operation and reject the resulting promise with a [`TimeoutException`](#timeoutexception).\n\nInternally, the given `$time` value will be used to start a timer that will\n*cancel* the pending operation once it triggers. This implies that if you\npass a really small (or negative) value, it will still start a timer and will\nthus trigger at the earliest possible time in the future.\n\nIf the input `$promise` is already settled, then the resulting promise will\nresolve or reject immediately without starting a timer at all.\n\nThis function takes an optional `LoopInterface|null $loop` parameter that can be used to\npass the event loop instance to use. You can use a `null` value here in order to\nuse the [default loop](https://github.com/reactphp/event-loop#loop). This value\nSHOULD NOT be given unless you're sure you want to explicitly use a given event\nloop instance.\n\nA common use case for handling only resolved values looks like this:\n\n```php\n$promise = accessSomeRemoteResource();\nReact\\Promise\\Timer\\timeout($promise, 10.0)-\u003ethen(function ($value) {\n    // the operation finished within 10.0 seconds\n});\n```\n\nA more complete example could look like this:\n\n```php\n$promise = accessSomeRemoteResource();\nReact\\Promise\\Timer\\timeout($promise, 10.0)-\u003ethen(\n    function ($value) {\n        // the operation finished within 10.0 seconds\n    },\n    function ($error) {\n        if ($error instanceof React\\Promise\\Timer\\TimeoutException) {\n            // the operation has failed due to a timeout\n        } else {\n            // the input operation has failed due to some other error\n        }\n    }\n);\n```\n\nOr if you're using [react/promise v3](https://github.com/reactphp/promise):\n\n```php\nReact\\Promise\\Timer\\timeout($promise, 10.0)-\u003ethen(function ($value) {\n    // the operation finished within 10.0 seconds\n})-\u003ecatch(function (React\\Promise\\Timer\\TimeoutException $error) {\n    // the operation has failed due to a timeout\n})-\u003ecatch(function (Throwable $error) {\n    // the input operation has failed due to some other error\n});\n```\n\nAs discussed above, the [`timeout()`](#timeout) function will take care of\nthe underlying operation if it takes *too long*. In this case, you can be\nsure the resulting promise will always be rejected with a\n[`TimeoutException`](#timeoutexception). On top of this, the function will\ntry to *cancel* the underlying operation. Responsibility for this\ncancellation logic is left up to the underlying operation.\n\n- A common use case involves cleaning up any resources like open network\n  sockets or file handles or terminating external processes or timers.\n\n- If the given input `$promise` does not support cancellation, then this is a\n  NO-OP. This means that while the resulting promise will still be rejected,\n  the underlying input `$promise` may still be pending and can hence continue\n  consuming resources\n\nOn top of this, the returned promise is implemented in such a way that it can\nbe cancelled when it is still pending. Cancelling a pending promise will\ncancel the underlying operation. As discussed above, responsibility for this\ncancellation logic is left up to the underlying operation.\n\n```php\n$promise = accessSomeRemoteResource();\n$timeout = React\\Promise\\Timer\\timeout($promise, 10.0);\n\n$timeout-\u003ecancel();\n```\n\nFor more details on the promise cancellation, please refer to the\n[Promise documentation](https://github.com/reactphp/promise#cancellablepromiseinterface).\n\nIf you want to wait for multiple promises to resolve, you can use the normal\npromise primitives like this:\n\n```php\n$promises = array(\n    accessSomeRemoteResource(),\n    accessSomeRemoteResource(),\n    accessSomeRemoteResource()\n);\n\n$promise = React\\Promise\\all($promises);\n\nReact\\Promise\\Timer\\timeout($promise, 10)-\u003ethen(function ($values) {\n    // *all* promises resolved\n});\n```\n\nThe applies to all promise collection primitives alike, i.e. `all()`,\n`race()`, `any()`, `some()` etc.\n\nFor more details on the promise primitives, please refer to the\n[Promise documentation](https://github.com/reactphp/promise#functions).\n\n### sleep()\n\nThe `sleep(float $time, ?LoopInterface $loop = null): PromiseInterface\u003cvoid\u003e` function can be used to\ncreate a new promise that resolves in `$time` seconds.\n\n```php\nReact\\Promise\\Timer\\sleep(1.5)-\u003ethen(function () {\n    echo 'Thanks for waiting!' . PHP_EOL;\n});\n```\n\nInternally, the given `$time` value will be used to start a timer that will\nresolve the promise once it triggers. This implies that if you pass a really\nsmall (or negative) value, it will still start a timer and will thus trigger\nat the earliest possible time in the future.\n\nThis function takes an optional `LoopInterface|null $loop` parameter that can be used to\npass the event loop instance to use. You can use a `null` value here in order to\nuse the [default loop](https://github.com/reactphp/event-loop#loop). This value\nSHOULD NOT be given unless you're sure you want to explicitly use a given event\nloop instance.\n\nThe returned promise is implemented in such a way that it can be cancelled\nwhen it is still pending. Cancelling a pending promise will reject its value\nwith a `RuntimeException` and clean up any pending timers.\n\n```php\n$timer = React\\Promise\\Timer\\sleep(2.0);\n\n$timer-\u003ecancel();\n```\n\n### ~~resolve()~~\n\n\u003e Deprecated since v1.8.0, see [`sleep()`](#sleep) instead.\n\nThe `resolve(float $time, ?LoopInterface $loop = null): PromiseInterface\u003cfloat\u003e` function can be used to\ncreate a new promise that resolves in `$time` seconds with the `$time` as the fulfillment value.\n\n```php\nReact\\Promise\\Timer\\resolve(1.5)-\u003ethen(function ($time) {\n    echo 'Thanks for waiting ' . $time . ' seconds' . PHP_EOL;\n});\n```\n\nInternally, the given `$time` value will be used to start a timer that will\nresolve the promise once it triggers. This implies that if you pass a really\nsmall (or negative) value, it will still start a timer and will thus trigger\nat the earliest possible time in the future.\n\nThis function takes an optional `LoopInterface|null $loop` parameter that can be used to\npass the event loop instance to use. You can use a `null` value here in order to\nuse the [default loop](https://github.com/reactphp/event-loop#loop). This value\nSHOULD NOT be given unless you're sure you want to explicitly use a given event\nloop instance.\n\nThe returned promise is implemented in such a way that it can be cancelled\nwhen it is still pending. Cancelling a pending promise will reject its value\nwith a `RuntimeException` and clean up any pending timers.\n\n```php\n$timer = React\\Promise\\Timer\\resolve(2.0);\n\n$timer-\u003ecancel();\n```\n\n### ~~reject()~~\n\n\u003e Deprecated since v1.8.0, see [`sleep()`](#sleep) instead.\n\nThe `reject(float $time, ?LoopInterface $loop = null): PromiseInterface\u003cnever\u003e` function can be used to\ncreate a new promise which rejects in `$time` seconds with a `TimeoutException`.\n\n```php\nReact\\Promise\\Timer\\reject(2.0)-\u003ethen(null, function (React\\Promise\\Timer\\TimeoutException $e) {\n    echo 'Rejected after ' . $e-\u003egetTimeout() . ' seconds ' . PHP_EOL;\n});\n```\n\nInternally, the given `$time` value will be used to start a timer that will\nreject the promise once it triggers. This implies that if you pass a really\nsmall (or negative) value, it will still start a timer and will thus trigger\nat the earliest possible time in the future.\n\nThis function takes an optional `LoopInterface|null $loop` parameter that can be used to\npass the event loop instance to use. You can use a `null` value here in order to\nuse the [default loop](https://github.com/reactphp/event-loop#loop). This value\nSHOULD NOT be given unless you're sure you want to explicitly use a given event\nloop instance.\n\nThe returned promise is implemented in such a way that it can be cancelled\nwhen it is still pending. Cancelling a pending promise will reject its value\nwith a `RuntimeException` and clean up any pending timers.\n\n```php\n$timer = React\\Promise\\Timer\\reject(2.0);\n\n$timer-\u003ecancel();\n```\n\n### TimeoutException\n\nThe `TimeoutException` extends PHP's built-in `RuntimeException`.\n\n\n#### getTimeout()\n\nThe `getTimeout(): float` method can be used to\nget the timeout value in seconds.\n\n## Install\n\nThe recommended way to install this library is [through Composer](https://getcomposer.org/).\n[New to Composer?](https://getcomposer.org/doc/00-intro.md)\n\nThis project follows [SemVer](https://semver.org/).\nThis will install the latest supported version:\n\n```bash\ncomposer require react/promise-timer:^1.11\n```\n\nSee also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.\n\nThis project aims to run on any platform and thus does not require any PHP\nextensions and supports running on legacy PHP 5.3 through current PHP 8+ and\nHHVM.\nIt's *highly recommended to use the latest supported PHP version* for this project.\n\n## Tests\n\nTo run the test suite, you first need to clone this repo and then install all\ndependencies [through Composer](https://getcomposer.org/):\n\n```bash\ncomposer install\n```\n\nTo run the test suite, go to the project root and run:\n\n```bash\nvendor/bin/phpunit\n```\n\n## License\n\nMIT, see [LICENSE file](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freactphp%2Fpromise-timer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freactphp%2Fpromise-timer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freactphp%2Fpromise-timer/lists"}