{"id":21884649,"url":"https://github.com/onehilltech/promises","last_synced_at":"2025-08-09T06:13:12.224Z","repository":{"id":47167024,"uuid":"96066104","full_name":"onehilltech/promises","owner":"onehilltech","description":"Promise/A+ library for JVM and Android","archived":false,"fork":false,"pushed_at":"2021-09-10T09:42:33.000Z","size":154,"stargazers_count":25,"open_issues_count":3,"forks_count":5,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-15T07:19:03.428Z","etag":null,"topics":["android","java","promises"],"latest_commit_sha":null,"homepage":"","language":"Java","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/onehilltech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-07-03T03:16:32.000Z","updated_at":"2023-03-10T11:59:32.000Z","dependencies_parsed_at":"2022-09-21T07:41:11.880Z","dependency_job_id":null,"html_url":"https://github.com/onehilltech/promises","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onehilltech%2Fpromises","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onehilltech%2Fpromises/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onehilltech%2Fpromises/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onehilltech%2Fpromises/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/onehilltech","download_url":"https://codeload.github.com/onehilltech/promises/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249023746,"owners_count":21199961,"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":["android","java","promises"],"created_at":"2024-11-28T10:15:07.610Z","updated_at":"2025-04-15T07:19:08.825Z","avatar_url":"https://github.com/onehilltech.png","language":"Java","readme":"promises\n==========\n\n\n[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Promises-brightgreen.svg?style=flat)](https://android-arsenal.com/details/1/6140)\n[![](https://jitpack.io/v/onehilltech/promises.svg)](https://jitpack.io/#onehilltech/promises)\n[![Build Status](https://travis-ci.org/onehilltech/promises.svg?branch=master)](https://travis-ci.org/onehilltech/promises)\n[![codecov](https://codecov.io/gh/onehilltech/promises/branch/master/graph/badge.svg)](https://codecov.io/gh/onehilltech/promises)\n\nPromise library for JVM and Android\n\n* Implements the [Promises/A+](https://promisesaplus.com/) specification from JavaScript\n* Built using Java 1.7, but designed for Java 1.8\n* Supports Java Lambda expressions\n* Android module allows resolve/reject callbacks to run on UI thread\n\n\n## Installation\n\n\u003e This library requires Java 1.8\n\n### Gradle\n\n```gradle\nrepositories {\n    maven { url \"https://jitpack.io\" \n      // https://docs.gradle.org/current/userguide/declaring_repositories.html#sec:repository-content-filtering\n      content {\n          // filter only artifacts with group \"com.onehilltech.promises\" for https://github.com/onehilltech/promises\n          includeGroup \"com.onehilltech.promises\"\n      }\n    }\n}\n\ndependencies {\n  // for JVM-only projects\n  compile 'com.onehilltech.promises:promises-jvm:x.y.z'\n  \n  // for Android projects (includes JVM automatically)\n  implementation 'com.onehilltech.promises:promises-android:x.y.z'\n}\n```\n\n## Quick Start\n\nThe simplest promise to create is one that is already resolved or rejected using\n`Promise.resolve` or `Promise.reject`, respectively.\n\n```java\n// resolved promise\nPromise.resolve (5);\n\n// rejected promise\nPromise.reject (new IllegalStateException (\"This is a rejected promise\"));\n```\n\nYou can also create a promise that is settled in the background. This is good when you need to \nperform some workload in the background, and notify the caller (or client) when the workload\nis resolved or rejected.\n\n```java\nPromise \u003cFoo\u003e p = new Promise \u003c \u003e (settlement -\u003e {\n  // settlement.resolve (foo);\n  // settlement.reject (ex);\n}); \n```\n\nIn this case, you must either invoke `settlement.resolve` with the resolved value, or\n`settlement.reject` with an exception. Any uncaught exceptions will automatically reject\nthe promise with the uncaught exception.\n\nAll promises are executed (or settled) when they are first created. To process\na promise's settlement, use either `then` or `_catch`. It does not matter when you\ncall `then` or `_catch`. If the promise is not settled, then the appropriate\nhandler will be called after the promise is settled. If the promise is settled,\nthen the appropriate handler will be called as soon as possible. \n\n\u003e **Important.** All handlers are executed on a separate thread.\n\n```java\nPromise.resolve (5)\n       .then (n -\u003e {\n         // n == 5\n         System.out.println (\"Resolved value: \" + n);\n         return null;\n       });\n\nPromise.reject (new IllegalStateException (\"This is a rejected promise\"))\n       ._catch (reason -\u003e {\n         // reason instanceof IllegalStateException\n         reason.printStackTrace ();\n         return null;\n       });\n```\n\nYou may notice that the handlers return `null` in the example above. This is because the\nhandler has the option of returning a value or a `Promise` that to used to resolve the value \nfor the next handler in the chain. If the handler does not a value or a `Promise`, then \n`null` is passed to the next handler.\n\n```java\nPromise.resolve (5)\n       .then (n -\u003e {\n         // n == 5\n         System.out.println (\"Resolved value: \" + n);\n         return value (10);\n       })\n       .then (n -\u003e {\n         // n == 10\n         System.out.println (\"Resolved value: \" + n);\n         return null;\n       });\n```\n\nNot all handlers will return a value or `Promise`. If you are in this situation, then you can use\nthe `ResolveNoReturn` and `RejectNoReturn` helper classes, or `resolved` and `rejected` helper\nmethods.\n\n```java\nimport static com.onehilltech.promises.Promise.resolved;\nimport static com.onehilltech.promises.Promise.rejected;\n\n// ...\n\nPromise.resolve (5)\n       .then (resolved (n -\u003e System.out.println (\"Resolved value: \" + n)))        // n == 5\n       ._catch (rejected (reason -\u003e reason.printStackTrace ()));\n```\n\n### Chaining Promises\n\nPromises can be chained to create a series of background workloads to be completed in\nstep order. Just use `then` to chain a series of background workloads, and `_catch` to\nhandle any rejection from the preceding promises.\n\n```java\nPromise.resolve (5)\n       .then (resolved (n -\u003e System.out.println (\"Resolved value: \" + n)))          // n == 5\n       .then (resolved (value -\u003e System.out.println (\"Resolved value: \" + value)))  // value == null\n       ._catch (rejected (reason -\u003e { }))\n       .then (this::doSomethingElse)\n       ._catch (Promise.ignoreReason);\n```\n\nIn the example above, we must point our several things. First, execution continues\nafter the first `_catch` if any of the preceding promises is rejected. If none of\nthe promises are rejected, then the first `_catch` is skipped. Second, we are using\nJava method references (i.e., `this::doSomethingElse`), which improves the readability\nof the code, and reduces verbosity. Lastly, `Promise.ignoreReason` is a special \nhandler that will catch the rejection and ignore the reason. This way, you do not have\nto write a bunch of empty handlers like the first `_catch`.\n\n### Await\n\nJavaScript introduced a concept called async/await for serial execution of promises. The\nmain idea the caller of `await` blocks until the promises is settled. The advantage of this\napproach is it makes promise code more readable because it removes promise chaining. We\nprovide a similar with this library, and it is simple to use. Below is example code that\nuses the `await` function to serialize promise execution.\n\n```java\nimport static com.onehilltech.promises.Promise.await;\n\n// ....\n\ntry\n{\n  int result = await (Promise.resolve (5));\n}\ncatch (Exception e)\n{\n  \n}\n```\n\nThe `await` function takes a `Promise`. The caller of the `await` function will block\nuntil the promise is settled (i.e., resolved or rejected). If the promise is resolved,\nit will return the resolved value. If the promise is rejected, it will throw the reason\nfor rejection.\n\n### Promise.all\n\nThe library implements `Promise.all`, which is resolved if **all** promises are resolved \nand rejected if **any** of the promises is rejected.\n\n### Promise.race\n\nThe library implements `Promise.race`, which is settled when the first promise is either \nresolved or rejected.\n\n## Android Support\n\n### Running on the UI Thread\n\nAll promises are settled on a background thread, and the handlers are called on a background\nthread. If you attempt to update the UI in the handler, then the Android framework will throw\nan exception. This is because you are updating the UI on a different thread than the one that\ncreate the UI elements (i.e., the main thread). To address the need for updating the UI in\nthe handler methods, the Android module provides `onUiThread` helper methods for running a \nhandler on the UI thread.\n\n```java\nimport static com.onehilltech.promises.Promise.resolved;\nimport static com.onehilltech.promises.Promise.rejected;\nimport static com.onehilltech.promises.RejectedOnUIThread.onUiThread;\nimport static com.onehilltech.promises.ResolvedOnUIThread.onUiThread;\n\n// ...\n\nPromise.resolve (\"Hello, World!\")\n       .then (onUiThread (resolved (str -\u003e this.label.setText (str))))\n       ._catch (onUiThread (rejected (reason -\u003e reason.printStackTrace ())));\n```\n\n\nHappy Coding!\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonehilltech%2Fpromises","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fonehilltech%2Fpromises","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonehilltech%2Fpromises/lists"}