{"id":20741105,"url":"https://github.com/robtimus/completion-stage","last_synced_at":"2026-02-05T22:04:57.570Z","repository":{"id":57204685,"uuid":"437953908","full_name":"robtimus/completion-stage","owner":"robtimus","description":"A port of Java's CompletionStage using promises","archived":false,"fork":false,"pushed_at":"2025-11-18T16:23:13.000Z","size":368,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-11-18T18:16:02.140Z","etag":null,"topics":["completablefuture","completionstage","javascript","promise","promises","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/robtimus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-12-13T16:55:37.000Z","updated_at":"2025-11-18T16:23:10.000Z","dependencies_parsed_at":"2023-02-15T18:00:57.632Z","dependency_job_id":"fbb0becf-1d5f-4767-ba64-34483f6ee50c","html_url":"https://github.com/robtimus/completion-stage","commit_stats":{"total_commits":19,"total_committers":2,"mean_commits":9.5,"dds":"0.10526315789473684","last_synced_commit":"f9c3fb1e5f648a00fdea49e33438fda8fcbd9404"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/robtimus/completion-stage","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robtimus%2Fcompletion-stage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robtimus%2Fcompletion-stage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robtimus%2Fcompletion-stage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robtimus%2Fcompletion-stage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/robtimus","download_url":"https://codeload.github.com/robtimus/completion-stage/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robtimus%2Fcompletion-stage/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29135955,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-05T21:59:57.939Z","status":"ssl_error","status_checked_at":"2026-02-05T21:59:57.628Z","response_time":65,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["completablefuture","completionstage","javascript","promise","promises","typescript"],"created_at":"2024-11-17T06:33:50.714Z","updated_at":"2026-02-05T22:04:57.543Z","avatar_url":"https://github.com/robtimus.png","language":"TypeScript","readme":"# completion-stage\n[![npm](https://img.shields.io/npm/v/completion-stage)](https://www.npmjs.com/package/completion-stage)\n[![Build Status](https://github.com/robtimus/completion-stage/actions/workflows/build.yml/badge.svg)](https://github.com/robtimus/completion-stage/actions/workflows/build.yml)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=robtimus%3Acompletion-stage\u0026metric=alert_status)](https://sonarcloud.io/summary/overall?id=robtimus%3Acompletion-stage)\n[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=robtimus%3Acompletion-stage\u0026metric=coverage)](https://sonarcloud.io/summary/overall?id=robtimus%3Acompletion-stage)\n[![Known Vulnerabilities](https://snyk.io/test/github/robtimus/completion-stage/badge.svg)](https://snyk.io/test/github/robtimus/completion-stage)\n\nA port of Java's [CompletionStage](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/CompletionStage.html) using [promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). [CompletableFuture](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/CompletableFuture.html) is also partially ported.\n\nThe following is an overview of how each `CompletionStage` method is implemented, where `future` in the left column is replaced by `promise` in the right.\n\n| CompletionStage                        | Promise                                       |\n| ---------------------------------------| --------------------------------------------- |\n| `future.acceptEither(other, action)`   | `Promise.race([promise, other]).then(action)` |\n| `future.applyToEither(other, fn)`      | `Promise.race([promise, other]).then(fn)`     |\n| `future.exceptionally(fn)`             | `promise.catch(fn)`                           |\n| `future.exceptionallyCompose(fn)`      | `promise.catch(fn)`                           |\n| `future.handle(fn)`                    | `handle(promise, fn)`                         |\n| `future.runAfterBoth(other, action)`   | `Promise.all([promise, other]).then(action)`  |\n| `future.runAfterEither(other, action)` | `Promise.race([promise, other]).then(action)` |\n| `future.thenAccept(action)`            | `promise.then(action)`                        |\n| `future.thenAcceptBoth(other, action)` | `Promise.all([promise, other]).then(action)`  |\n| `future.thenApply(fn)`                 | `promise.then(fn)`                            |\n| `future.thenCombine(other, fn)`        | `Promise.all([promise, other]).then(fn)`      |\n| `future.thenCompose(fn)`               | `promise.then(fn)`                            |\n| `future.thenRun(action)`               | `promise.then(fn)`                            |\n| `future.toCompletableFuture()`         | N/A                                           |\n| `future.whenComplete(action)`          | `whenComplete(promise, action)`               |\n\nIn addition, the following is an overview of `CompletableFuture` methods that are implemented using promises.\n\n| CompletableFuture                                                 | Promise                                                     |\n| ----------------------------------------------------------------- | ----------------------------------------------------------- |\n| `CompletableFuture.allOf(future1, future2)`                       | `Promise.all([promise1, promise2])`\u003csup\u003e1\u003c/sup\u003e             |\n| `CompletableFuture.anyOf(future1, future2)`                       | `Promise.race([promise1, promise2])`\u003csup\u003e2\u003c/sup\u003e            |\n| `CompletableFuture.completedFuture(value)`                        | `Promise.resolve(value)`                                    |\n| `CompletableFuture.completedStage(value)`                         | `Promise.resolve(value)`                                    |\n| `future.completeOnTimeout(value, timeout, TimeUnit.MILLISECONDS)` | `resolveOnTimeout(promise, value, timeout)`\u003csup\u003e3\u003c/sup\u003e     |\n| `CompletableFuture.failedFuture(ex)`                              | `Promise.reject(ex)`                                        |\n| `CompletableFuture.failedStage(ex)`                               | `Promise.reject(ex)`                                        |\n| `future.orTimeout(timeout, TimeUnit.MILLISECONDS)`                | `rejectOnTimeout(promise, timeout)`\u003csup\u003e3\u003c/sup\u003e\u003csup\u003e4\u003c/sup\u003e |\n| `CompletableFuture.runAsync(action)`                              | `supply(action)`\u003csup\u003e5\u003c/sup\u003e                                |\n| `CompletableFuture.supplyAsync(supplier)`                         | `supply(supplier)`\u003csup\u003e5\u003c/sup\u003e                              |\n\n\u003csup\u003e\u003csup\u003e1\u003c/sup\u003e: whereas `CompletableFuture.allOf` returns a `CompletableFuture\u003cVoid\u003e`, the generic type of the promise returned by `Promise.all` is a combination of the generic types of each passed promise.\u003c/sup\u003e\\\n\u003csup\u003e\u003csup\u003e2\u003c/sup\u003e: whereas `CompletableFuture.anyOf` returns a `CompletableFuture\u003cObject\u003e`, the generic type of the promise returned by `Promise.race` is the union of the generic types of each passed promise.\u003c/sup\u003e\\\n\u003csup\u003e\u003csup\u003e3\u003c/sup\u003e: the timeouts for `resolveOnTimeout` and `rejectOnTimeout` can only be given as milliseconds.\u003c/sup\u003e\\\n\u003csup\u003e\u003csup\u003e4\u003c/sup\u003e: an optional rejection reason can be given as a function. The result of this function is used as rejection reason upon timeout.\u003c/sup\u003e\\\n\u003csup\u003e\u003csup\u003e5\u003c/sup\u003e: an optional delay in milliseconds can be given.\u003c/sup\u003e\n\nNote that [promise.then](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then), [promise.catch](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch) and `supply` can be used in the same way where `CompletionStage` and `CompletableFuture` need multiple methods. Which `CompletionStage` or `CompletableFuture` method is implemented depends on the return value of the function passed to `promise.then`, `promise.catch` or `supply`.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobtimus%2Fcompletion-stage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobtimus%2Fcompletion-stage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobtimus%2Fcompletion-stage/lists"}