{"@context":"https://w3id.org/codemeta/3.0","@type":"SoftwareSourceCode","identifier":"pkg:golang/github.com/b97tsk/async","name":"github.com/b97tsk/async","description":"Package async is a library for asynchronous programming.\n\nSince Go has already done a great job in bringing green/virtual threads\ninto life, this library only implements a single-threaded Executor type,\nwhich some refer to as an async runtime.\nOne can create as many executors as they like.\n\nWhile Go excels at forking, async, on the other hand, excels at joining.\n\nWanted to execute pieces of code from goroutines in a single-threaded way?\n\nAn Executor is designed to be able to run tasks spawned in goroutines\nsequentially.\nThis comes in handy when one wants to do a series of operations\non a single thread, for example, to read or update states that are not\nsafe for concurrent access, to write data to the console or a file, to\nupdate one's user interfaces, etc.\n\nBe aware that there is no back pressure.\nTask spawning isn't designed to block.\nIf spawning outruns execution, an Executor can easily consume a lot of\nmemory over time.\nTo mitigate, one could introduce a semaphore per hot spot.\n\nAn async Task can be reactive.\n\nAn async Task is spawned with a Coroutine to take care of it.\nIn this user-provided function, one can return a specific Result to tell\na coroutine to watch and await some events (e.g. Signal, State and\nMemo, etc.), and the coroutine can just re-run the task whenever any of\nthese events notifies.\n\nThis is useful when one wants to do something repeatedly.\nIt works like a loop. To exit this loop, just return a Result that does\nsomething different from within the task function. Simple.\n\nA Coroutine can also make a transition from one Task to another, just\nlike a state machine can make a transition from one state to another.\nThis is done by returning another specific Result from within a task\nfunction.\nA coroutine can transition from one task to another until a task ends it.\n\nWith the ability to transition, async is able to provide more advanced\ncontrol structures, like Block, Loop and Func, to ease the process of\nwriting async code. The experience now feels similar to that of writing sync\ncode.\n\nIt's not recommended to have channel operations in an async Task for\na Coroutine to do, since they tend to block.\nFor an Executor, if one coroutine blocks, no other coroutines can run.\nSo instead of passing data around, one would just handle data at places\nwhere data are available.\nAsync tasks are quite flexible and composable. One can even build a state\nmachine across goroutine boundaries, which isn't something channels are\nqualified to do. Async tasks are better building blocks than channels.\n\nOne of the advantages of passing data over channels is to be able to avoid\nallocation. Unfortunately, async tasks always escape to heap.\nAny variable they capture also escapes to heap. One should stay alert and\ntake measures in hot spots, like repeatedly using a same task.\n\nAsync encourages non-blocking programming, which makes structured concurrency\nquite essential to this library.\nAt some point, one might want to know when an Executor stops operating.\n\nIn Go, all Go code can only be executed by goroutines.\nAsync tasks are just ordinary Go functions, too.\nIf one keeps track of every goroutine that spawns async tasks, and waits for\nthem to finish, then the exact right time when an Executor stops operating\ncan be determined too.\nEssentially, it creates a synchronization point between the spawned tasks\nand the rest of the code after the waiting.\n\n\nThis example demonstrates how a task can conditionally depend on a state.\n\n\nThis example demonstrates how a memo can conditionally depend on a state.\n\n\nThis example demonstrates how to end a task.\nIt creates a task that prints the value of a state whenever it changes.\nThe task only prints 0, 1, 2 and 3 because it is ended after 3.\n\n\nThis example demonstrates how to use memos to memoize cheap computations.\nMemos are evaluated lazily. They take effect only when they are acquired.\n\n\nThis example demonstrates how to set up an autorun function to run\nan executor in a goroutine automatically whenever a coroutine is spawned or\nresumed.\n\n\nThis example demonstrates how async handles panics.\n\n\nThis example demonstrates how a coroutine can transition from one task to\nanother.","version":"v0.18.0","softwareVersion":"v0.18.0","license":"https://spdx.org/licenses/MIT","codeRepository":"https://github.com/b97tsk/async","issueTracker":"https://github.com/b97tsk/async/issues","url":"https://github.com/b97tsk/async","programmingLanguage":{"@type":"ComputerLanguage","name":"Go"},"dateCreated":"2024-12-25","dateModified":"2026-03-14","datePublished":"2026-03-14","copyrightYear":2024,"downloadUrl":"https://proxy.golang.org/github.com/b97tsk/async/@v/v0.18.0.zip","softwareHelp":{"@type":"WebSite","url":"https://pkg.go.dev/github.com/b97tsk/async#section-documentation"},"applicationCategory":"go","runtimePlatform":"go","developmentStatus":"active","sameAs":["https://pkg.go.dev/github.com/b97tsk/async"]}