{"id":13465462,"url":"https://github.com/async-plus/async-plus","last_synced_at":"2025-03-25T16:31:47.520Z","repository":{"id":42470472,"uuid":"463655318","full_name":"async-plus/async-plus","owner":"async-plus","description":"⛓ A chainable interface for Swift's async/await.","archived":false,"fork":false,"pushed_at":"2024-04-29T14:43:14.000Z","size":313,"stargazers_count":202,"open_issues_count":3,"forks_count":8,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-20T23:04:46.246Z","etag":null,"topics":["async","async-await","await","chainable","concurrency","flatmap","future","futures","promise","promises","swift","swift5"],"latest_commit_sha":null,"homepage":"https://asyncplus.codes","language":"Swift","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/async-plus.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":"2022-02-25T19:40:17.000Z","updated_at":"2025-03-07T16:22:57.000Z","dependencies_parsed_at":"2024-07-31T15:01:28.282Z","dependency_job_id":"35dd0b2b-ae81-4229-91e3-47aeaa676706","html_url":"https://github.com/async-plus/async-plus","commit_stats":{"total_commits":90,"total_committers":3,"mean_commits":30.0,"dds":"0.033333333333333326","last_synced_commit":"c99c106ac4a6275f0a9507c3dd722ecd74c323d3"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/async-plus%2Fasync-plus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/async-plus%2Fasync-plus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/async-plus%2Fasync-plus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/async-plus%2Fasync-plus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/async-plus","download_url":"https://codeload.github.com/async-plus/async-plus/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245500257,"owners_count":20625537,"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":["async","async-await","await","chainable","concurrency","flatmap","future","futures","promise","promises","swift","swift5"],"created_at":"2024-07-31T15:00:30.472Z","updated_at":"2025-03-25T16:31:47.239Z","avatar_url":"https://github.com/async-plus.png","language":"Swift","funding_links":[],"categories":["Libs","Swift"],"sub_categories":["Concurrency"],"readme":"\u003ca href=\"https://discord.gg/vaAhGvvHpW\"\u003e![async+](Images/heading.png)\u003c/a\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://docs.asyncplus.codes\"\u003e\u003cimg src=\"https://img.shields.io/badge/read%20the-docs-blue\" alt=\"Documentation\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://discord.gg/vaAhGvvHpW\"\u003e\u003cimg src=\"https://img.shields.io/discord/946863161460547684.svg\" alt=\"Team Chat\"\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-brightgreen.svg\" alt=\"MIT License\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/async-plus/async-plus/actions\"\u003e\u003cimg src=\"https://github.com/async-plus/async-plus/workflows/test/badge.svg\" alt=\"Continuous Integration\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://swift.org\"\u003e\u003cimg src=\"https://img.shields.io/badge/swift-5.5-brightgreen.svg\" alt=\"Swift 5.5\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://twitter.com/async_plus\"\u003e\u003cimg src=\"https://img.shields.io/badge/twitter-async__plus-5AA9E7.svg\" alt=\"Twitter\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003cbr\u003e\n\nAsync+ for Swift provides a simple **chainable interface** for your async and throwing code, similar to promises and futures.  Have the best of both worlds: you can use the async solution built into the language, but keep all the useful features of promises.\n\n### ✏️  Usage\n\nBasic chaining operations are:\n\n* `.then` arranges blocks one after another, passing along any values\n* `.recover` recovers from a thrown error with a backup value (or block to run)\n* `.catch` catches any errors (and allows you to throw new ones for later catch blocks)\n* `attempt { ... }` kicks off a chain as in the example below:\n\n```swift\nattempt {\n    return try await getThing()\n}.recover {\n    error in\n    return try await backupGetThing(error)\n}.then {\n    thing in\n    await thing.doYour()\n}.catch {\n    error in\n    alert(error)\n}\n```\n\nFor comparison, if we tried to write the above flow without Async+ we'd get something like this:\n\n\n  ```swift\n  Task.init {\n      do {\n          let thing: Thing\n          do {\n              thing = try await getThing()\n          } catch {\n              thing = try await backupGetThing(error)\n          }\n          await thing.doYour()\n      } catch {\n          error in\n          alert(error)\n      }\n  }\n  ```\n\nAsync+ allows async and/or throwing code to remain unnested, modular, and concise.  For a full list of operations see the [documentation](https://docs.asyncplus.codes).\n\nWant to still use chained code within a `do`/`catch` block, `Task.init`, or similar context? Easy: chains are fully interoperable with async and/or throwing contexts via the operations `.async()`, and `.asyncThrows()` at the end of the chain, for example:\n\n```\nlet foo = await attempt{ ... }.then{ ... }.async() // non-throwing chain\nlet foo = try await attempt{ ... }.then{ ... }.asyncThrows() // throwing chain\n```\nIf the chain doesn't throw you will not be able to call `asyncThrows` on it (it is a `Guarantee\u003cT\u003e` type rather than a `Promise\u003cT\u003e` type), and vice versa.  Similarly, chains with potential for uncaught errors will raise an unused value warning at compilation time.\n\n### 💾  Installation\n\nAsync+ can be installed with either SwiftPM or CocoaPods.\n\nFor **SwiftPM**, in Xcode go to `\u003cyour project\u003e -\u003e \u003cProjectName\u003e -\u003e Package Dependencies -\u003e \"+\"` and enter: `https://github.com/async-plus/async-plus.git`\n\nOr modify your `Package.swift` file:\n\n```swift\ndependencies: [\n    .Package(url: \"https://github.com/async-plus/async-plus.git\", majorVersion: 1, minor: 1),\n] \n```\n\nFor **CocoaPods**, in your [Podfile](https://guides.cocoapods.org/syntax/podfile.html):\n\n```\ntarget \"Change Me!\" do\n  pod \"AsyncPlus\", \"~\u003e 1.1\"\nend\n```\n\nTo use Async+ in a Swift file you must `import AsyncPlus` at the top of the file.\n\n###  📘  Documentation\n\n[Getting Started](https://docs.asyncplus.codes/getting-started/)\n\n[Operations](https://docs.asyncplus.codes/operations/)\n\n[Using chains from async or throwing contexts](https://docs.asyncplus.codes/async-or-throwing-contexts/)\n\n[Motivation and common patterns](https://docs.asyncplus.codes/motivation-and-common-patterns/)\n\n[Cancellation](https://docs.asyncplus.codes/cancellation/)\n\n[Migrating from PromiseKit](https://docs.asyncplus.codes/migrating-from-promisekit/)\n\n[Frequently asked questions (FAQ)](https://docs.asyncplus.codes/faq/)\n\n### 🚀  Feedback and Contributing\n\nThis package is in its initial release: please provide feedback and suggestions in order to help shape the API, either by submitting an [issue](https://github.com/async-plus/async-plus/issues/new) on Github or sending a message on [Discord](https://discord.gg/vaAhGvvHpW).\n\nSpecial thanks to the developers of PromiseKit and [mxcl](https://github.com/mxcl) for inspiring this work and promoting its development.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasync-plus%2Fasync-plus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fasync-plus%2Fasync-plus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasync-plus%2Fasync-plus/lists"}