{"id":16665271,"url":"https://github.com/bobkerns/better-future","last_synced_at":"2025-08-13T22:04:07.615Z","repository":{"id":148566305,"uuid":"607454238","full_name":"BobKerns/better-future","owner":"BobKerns","description":"Futures (deferred/lazy evaluation), with cancellation, timeouts, task groups and pools, working fully w/ Promises.","archived":false,"fork":false,"pushed_at":"2025-05-25T10:37:48.000Z","size":452,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-25T11:31:06.049Z","etag":null,"topics":["asynchronous-programming","lazy-evaluation","promise-library","promises"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/BobKerns.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-28T02:02:33.000Z","updated_at":"2025-05-25T10:37:45.000Z","dependencies_parsed_at":"2023-05-20T13:46:00.662Z","dependency_job_id":null,"html_url":"https://github.com/BobKerns/better-future","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":"BobKerns/npm-typescript-rollup-template","purl":"pkg:github/BobKerns/better-future","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BobKerns%2Fbetter-future","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BobKerns%2Fbetter-future/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BobKerns%2Fbetter-future/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BobKerns%2Fbetter-future/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BobKerns","download_url":"https://codeload.github.com/BobKerns/better-future/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BobKerns%2Fbetter-future/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270323579,"owners_count":24564684,"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","status":"online","status_checked_at":"2025-08-13T02:00:09.904Z","response_time":66,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["asynchronous-programming","lazy-evaluation","promise-library","promises"],"created_at":"2024-10-12T11:06:26.557Z","updated_at":"2025-08-13T22:04:07.555Z","avatar_url":"https://github.com/BobKerns.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# better-future: Better handling of deferred task compatible with Promises\n\nA general-purpose package for managing deferred or parallel tasks. Main features include:\n\n## Futures\n\n* 100% compatible with `Promise` API.\n* Lazy evaluation\n* Cancellation\n* Pause/resume\n* Initial delay\n* Implemented on top of Javascript `Promise` implementation. Does not reinvent the wheel,\n  helping to ensure consistent semantics.\n\n## Task groups\n\n* _Awaitaable_: You can `await` completion (or failure) of the combined set of tasks.\n* _Background tasks_: These do not directly contribute to the task result, but should\n  complete before the task completes.\n* _Daemon Tasks_: These do not directly contribute to the task result, but should be\n  terminated when the task resolves.\n* _Filters_ strip down large data early, miimizing memory usage.\n* _Data aggregation- (map/reduce). Reducers can often accumulate results in O(1) space.\n  * For example, average, RMS/quadratic mean, standard deviation (population \u0026 sample), bincount\n\n## Task pools\n\n* Task pools limit simultaneous execution, with its impact\n  on memory usage and latency.\n* Combined with an initial delay, can achieve a form of rate limiting.\n* Very useful for web scraping applications.\n\n## Possible future additions\n\n### Infinite tasks\n\nThese would produce an async generator. These would be useful for monitoring real-time event streams,\ncalciulating things like moving averages.\n\n## `Promise`-based publish/subscribe\n\nCombined with Infinite tasks_, this would allow multiple consumers of an event stream\n\n## Motivation\n\nThis package grew out of finding I needed something I'd written many times before\nin Javascript (and in other forms even before).\n\nThe scenario is this:\n\nYou have a computation task. You don't know if you will need the result. Typically, there will be many\nof these tasks, and you will only need a few of them.\n\nYou could return a function that you call when you need the result, and build adaptors for everything\nthat uses them.\n\nBut your asynchronous task will return a `Promise`, and your consumers of that are likely to expect a\n`Promise`. And you'd find yourself needing to cache the results, and to potentially notify multiple\nawaiting consumers when results are available.\n\nIn short, we need something very much like a `Promise`, but for a future result.\n\nWhen you do this at scale, you find you need features like timeouts, cancellation, aggregation of results,\nresource management, memory optimization, etc.\n\n## A note about terminology\n\nUnfortunately, terminology has divered over the years between different communities. What python and Java call a \"Future\"\nroughly corresponds to a `Promise` + cancellation. A \"Task\" in python is a scheduable coroutine that is also awaitable.\n\nAlthough the core concepts overlap, it's best not to try to map the concepts between languages. There are differences\ndue to python's convoluted async history, and there are differences due to how the runtimes operate.\n\nThe key terms here:\n\n* `Promise`: always refers to a Javascript Promise\n* _thenable_: An object with a compliant `.then()` method. This includes instances of `Promise`,\n  [`Future`](api/classes/Future.html),\n  and predecessors to Javascript's `Promise` class.\n* [`Future`](api/classes/Future.html): A `Promise`-like _thenable_ that offers delayed/lazy execution, timeouts, and\n  cancellation.\n* _Task_: A computation to be managed by a [`Future`](api/classes/Future.html). This will typically be an async function\n  returning a `Promise`, but that is not a requirement. In the default case, they should take exactly zero arguments, or\n  two arguments like he argment to `Promise`.\n\n## Basic API\n\nThe familiar `Promise` API is here, including the static methods such as `Promise.race`. A [`Future`](api/classes/Future.html) implements `.then()`, `.catch()`, and `.finally()`, and thus can be used\nanywhere a `Promise` can be.\n\nThe [`Future`](api/classes/Future.html) API includes two key additions: [`.start()`](api/classes/Future.html#start) and\n[`.when()`](api/classes/Future.html#when).\n\nUnlike a `Promise`, a [`Future`](api/classes/Future.html) does not begin\nwork until either [`Future`.`start`()](api/classes/Future.htm#start) is called, or [`Future`.`then`()](api/classes/Future.html#then), indicating a consumer for the information.\n\n[`Future``.when`()])api/classes/Future.html#when) is just like [`Future`.`then`()](api/classes/Future.html#then)\nwithout the [`Future`.`start`()](api/classes/Future.htm#start). This is useful for passive consumers of the information.\nFor examplee:\n\n```typescript\nreturn new Future(() =\u003e fetch(DATA_URL)).when(v =\u003e (console.log(\"data: \", v), v);\n```\n\nThis also illustrates another feature: The [`Future`)api/classes/Future.html#constructor) can accept\na function of zero arguments, and it will seamlessly be adapted to the `(resolved, rejected) =\u003e void`\npattern accepted by `Promise`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbobkerns%2Fbetter-future","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbobkerns%2Fbetter-future","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbobkerns%2Fbetter-future/lists"}