{{Short description|Feature of programming languages}}
In [[computer programming]], the '''async/await pattern''' is a syntactic feature of many [[programming language]]s that allows an [[Asynchrony (computer programming)|asynchronous]], [[non-blocking I/O|non-blocking]] [[Subroutine|function]] to be structured in a way similar to an ordinary synchronous function.
It is semantically related to the concept of a [[coroutine]] and is often implemented using similar techniques, and is primarily intended to provide opportunities for the program to execute other code while waiting for a long-running, asynchronous task to complete, usually represented by [[Futures and promises|promises]] or similar [[data structure]]s. The feature is found in [[C Sharp 5.0|C#]],<ref name="Skeet" />{{rp|10}} [[C++]], [[Python (programming language)|Python]], [[F Sharp (programming language)|F#]], [[Hack (programming language)|Hack]], [[Julia (programming language)|Julia]], [[Dart (programming language)|Dart]], [[Kotlin (programming language)|Kotlin]], [[Rust (programming language)|Rust]],<ref>{{Cite web|title=Announcing Rust 1.39.0 | url=https://blog.rust-lang.org/2019/11/07/Rust-1.39.0.html|language=en|access-date=2019-11-07}}</ref> [[Nim (programming language)|Nim]],<ref>{{Cite web |title=std/async |url=https://nim-lang.org/docs/async.html |url-status=live |archive-url=https://web.archive.org/web/20250929052212/https://nim-lang.org/docs/async.html |archive-date=29 Sep 2025 |access-date=2020-01-19 |language=en}}</ref> [[ES2017|JavaScript]], and [[Swift (programming language)|Swift]].<ref>{{Cite web|title=Concurrency — The Swift Programming Language (Swift 5.5)|url=https://docs.swift.org/swift-book/LanguageGuide/Concurrency.html|access-date=2021-09-28|website=docs.swift.org}}</ref>
== History == F# added asynchronous workflows with await points in version 2.0 in 2007.<ref>{{Cite book|chapter-url=https://link.springer.com/chapter/10.1007/978-3-642-18378-2_15|language=en|access-date=2021-04-29|publisher=Springer Link|series=Lecture Notes in Computer Science|year=2011|doi=10.1007/978-3-642-18378-2_15|last1=Syme|first1=Don|last2=Petricek|first2=Tomas|last3=Lomov|first3=Dmitry|title=Practical Aspects of Declarative Languages |chapter=The F# Asynchronous Programming Model |volume=6539|pages=175–189|isbn=978-3-642-18377-5}}</ref> This influenced the async/await mechanism added to C#.<ref>{{Cite web|title=The Early History of F#, HOPL IV|language=en|access-date=2021-04-29|url=https://dl.acm.org/toc/pacmpl/2020/4/HOPL|website=ACM Digital Library}}</ref>
Microsoft first released a version of C# with async/await in the Async CTP (2011). It was later officially released in C# 5 (2012).<ref>{{cite web |last1=Hejlsberg |first1=Anders |title=Anders Hejlsberg: Introducing Async – Simplifying Asynchronous Programming |url=https://channel9.msdn.com/Blogs/Charles/Anders-Hejlsberg-Introducing-Async |website=Channel 9 MSDN |publisher=Microsoft |access-date=5 January 2021 |language=en}}</ref><ref name=Skeet/>{{rp|10}}
[[Haskell]] lead developer [[Simon Marlow]] created the async package in 2012.<ref>{{cite web |title=async: Run IO operations asynchronously and wait for their results |url=https://hackage.haskell.org/package/async |website=Hackage}}</ref>
Python added support for async/await with version 3.5 in 2015<ref>{{cite web |title=What's New In Python 3.5 — Python 3.9.1 documentation |url=https://docs.python.org/3/whatsnew/3.5.html |website=docs.python.org |access-date=5 January 2021}}</ref> adding 2 new [[Keyword (computer languages)|keywords]], <code>async</code> and <code>await</code>.
[[TypeScript]] added support for async/await with version 1.7 in 2015.<ref>{{cite web |last1=Gaurav |first1=Seth |title=Announcing TypeScript 1.7 |url=https://devblogs.microsoft.com/typescript/announcing-typescript-1-7/ |website=TypeScript |publisher=Microsoft |access-date=5 January 2021 |date=30 November 2015}}</ref>
JavaScript added support for async/await in 2017 as part of [[ECMAScript]] 2017 JavaScript edition.
Rust added support for async/await with version 1.39.0 in 2019 using the <code>async</code> keyword and the <code>.await</code> postfix operator, both introduced in the 2018 edition of the language.<ref>{{cite web |last1=Matsakis |first1=Niko |title=Async-await on stable Rust! {{!}} Rust Blog |url=https://blog.rust-lang.org/2019/11/07/Async-await-stable.html |website=blog.rust-lang.org |publisher=Rust Blog |access-date=5 January 2021 |language=en}}</ref>
C++ added support for async/await with [[C++20|version 20]] in 2020 with 3 new keywords <code>co_return</code>, <code>co_await</code>, <code>co_yield</code>.
Swift added support for async/await with [https://docs.swift.org/swift-book/LanguageGuide/Concurrency.html version 5.5] in 2021, adding 2 new keywords <code>async</code> and <code>await</code>. This was released alongside a concrete implementation of the [[Actor model]] with the <code>actor</code> keyword<ref>{{Cite web | url=https://docs.swift.org/swift-book/LanguageGuide/Concurrency.html#ID645 | title=Concurrency — the Swift Programming Language (Swift 5.6) }}</ref> which uses async/await to mediate access to each actor from outside.
== Example ==
The [[C Sharp 5.0|C#]] function below, which downloads a resource from a [[URI]] and returns the resource's length, uses this async/await pattern:
<syntaxhighlight lang="csharp"> using System; using System.Net.Http; using System.Threading.Tasks;
public async Task<int> FindSizeOfPageAsync(Uri uri) { HttpClient client = new(); byte[] data = await client.GetByteArrayAsync(uri); return data.Length; } </syntaxhighlight>
* First, the <code>async</code> keyword indicates to C# that the method is asynchronous, meaning that it may use an arbitrary number of <code>await</code> expressions and will bind the result to a [[futures and promises|promise]].<ref name=Skeet>{{cite book |last=Skeet|first=Jon|title= C# in Depth |date=23 March 2019 |publisher= Manning |isbn= 978-1617294532}}</ref>{{rp|165-168}} * The [[return type]], <code>Task<T></code>, is C#'s analogue to the concept of a promise, and here is indicated to have a result value of type <code>int</code>. * The first expression to execute when this method is called will be <code>new HttpClient().GetByteArrayAsync(uri)</code>,<ref name=Albahari/>{{rp|189-190, 344}}<ref name=Skeet/>{{rp|882}} which is another asynchronous method returning a <code>Task<byte[]></code>. Because this method is asynchronous, it will not download the entire batch of data before returning. Instead, it will begin the download process using a non-blocking mechanism (such as a [[Thread (computer programming)|background thread]]), and immediately return an unresolved, unrejected <code>Task<byte[]></code> to this function. * With the <code>await</code> keyword attached to the <code>Task</code>, this function will immediately proceed to return a <code>Task<int></code> to its caller, who may then continue on with other processing as needed. * Once <code>GetByteArrayAsync()</code> finishes its download, it will resolve the <code>Task</code> it returned with the downloaded data. This will trigger a [[Callback (computer programming)|callback]] and cause <code>FindPageSizeAsync()</code> to continue execution by assigning that value to <code>data</code>. * Finally, the method returns <code>data.Length</code>, a simple [[integer]] indicating the length of the array. The [[compiler]] re-interprets this as resolving the <code>Task</code> it returned earlier, triggering a callback in the method's caller to do something with that length value.
A function using async/await can use as many <code>await</code> expressions as it wants, and each will be handled in the same way (though a promise will only be returned to the caller for the first await, while every other await will utilize internal callbacks). A function can also hold a promise object directly and do other processing first (including starting other asynchronous tasks), delaying awaiting the promise until its result is needed. Functions with promises also have promise aggregation methods that allow the program to await multiple promises at once or in some special pattern (such as C#'s <code>Task.WhenAll()</code>,<ref name=Skeet/>{{rp|174-175}}<ref name=Albahari/>{{rp|664-665}} which returns a valueless <code>Task</code> that resolves when all of the tasks in the arguments have resolved). Many promise types also have additional features beyond what the async/await pattern normally uses, such as being able to set up more than one result callback or inspect the progress of an especially long-running task.
In the particular case of C#, and in many other languages with this language feature, the async/await pattern is not a core part of the language's runtime, but is instead implemented with [[lambda (programming)|lambdas]] or [[continuation]]s at compile time. For instance, the C# compiler would likely translate the above code to something like the following before translating it to its IL [[bytecode]] format:
<syntaxhighlight lang="csharp"> using System; using System.Net.Http; using System.Threading.Tasks;
public Task<int> FindSizeOfPageAsync(Uri uri) { HttpClient client = new(); Task<byte[]> dataTask = client.GetByteArrayAsync(uri); Task<int> afterDataTask = dataTask.ContinueWith((originalTask) => { return originalTask.Result.Length; }); return afterDataTask; } </syntaxhighlight>
Because of this, if an interface method needs to return a promise object, but itself does not require <code>await</code> in the body to wait on any asynchronous tasks, it does not need the <code>async</code> modifier either and can instead return a promise object directly. For instance, a function might be able to provide a promise that immediately resolves to some result value (such as C#'s <code>Task.FromResult()</code><ref name=Albahari>{{cite book |last=Albahari |first=Joseph |title= C# 10 in a Nutshell |date=2022 |publisher= O'Reilly |isbn= 978-1-098-12195-2}}</ref>{{rp|656}}), or it may simply return another method's promise that happens to be the exact promise needed (such as when deferring to an [[Overload (computer programming)|overload]]).
One important caveat of this functionality, however, is that while the code resembles traditional blocking code, the code is actually non-blocking and potentially multithreaded, meaning that many intervening events may occur while waiting for the promise targeted by an <code>await</code> to resolve. For instance, the following code, while always succeeding in a blocking model without <code>await</code>, may experience intervening events during the <code>await</code> and may thus find shared state changed out from under it:
<syntaxhighlight lang="csharp"> using System; using System.Diagnostics; using System.Net.Http;
string name = state.name; HttpClient client = new(); byte[] data = await client.GetByteArrayAsync(uri);
// Potential failure, as value of state.a may have been changed // by the handler of potentially intervening event. Debug.Assert(name == state.name);
return data.Length; </syntaxhighlight>
== Implementations ==
=== C ===
The [[C language]] does not support await/async. Some coroutine libraries such as ''s_task''<ref>{{cite web|url=https://github.com/xhawk18/s_task | title=s_task - awaitable coroutine library for C | website=[[GitHub]] }}</ref> simulate the keywords await/async with macros.
<syntaxhighlight lang="c"> #include <stdio.h> #include "s_task.h"
constexpr int STACK_SIZE = 64 * 1024 / sizeof(int);
// define stack memory for tasks int g_stack_main[STACK_SIZE]; int g_stack0[STACK_SIZE]; int g_stack1[STACK_SIZE];
void sub_task(__async__, void* arg) { int n = (int)(size_t)arg; for (int i = 0; i < 5; ++i) { printf("task %d, delay seconds = %d, i = %d\n", n, n, i); s_task_msleep(__await__, n * 1000); // s_task_yield(__await__); } }
void main_task(__async__, void* arg) { // create two sub-tasks s_task_create(g_stack0, sizeof(g_stack0), sub_task, (void*)1); s_task_create(g_stack1, sizeof(g_stack1), sub_task, (void*)2);
for (int i = 0; i < 4; ++i) { printf("task_main arg = %p, i = %d\n", arg, i); s_task_yield(__await__); }
// wait for the sub-tasks for exit s_task_join(__await__, g_stack0); s_task_join(__await__, g_stack1); }
int main(int argc, char* argv[]) { s_task_init_system();
// create the main task s_task_create(g_stack_main, sizeof(g_stack_main), main_task, (void*)(size_t)argc); s_task_join(__await__, g_stack_main); printf("all task is over\n"); return 0; } </syntaxhighlight>
=== C++ ===
In C++, await (named <code>co_await</code> in C++ to emphasise its context in coroutines) has been officially merged into [[C++20]].<ref>{{cite web|url=https://hub.packtpub.com/iso-c-committee-announces-that-c20-design-is-now-feature-complete/|title=ISO C++ Committee announces that C++20 design is now feature complete|date=25 February 2019}}</ref> Support for it, coroutines, and the keywords such as <code>co_await</code> are available in [[GNU Compiler Collection|GCC]] and [[MSVC]] compilers while [[Clang]] has partial support. A proper task class, <code>std::execution::task</code>, was introduced in [[C++26]].<ref>{{Cite web|title=Add a Coroutine Task Type|url=https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3552r2.pdf|publisher=WG21|author=Dietmar Kühl, Maikel Nadolski|date=18 May 2025|website=open-std.org}}</ref> To call it, use <code>std::execution::sync_wait()</code>, which returns <code>std::optional<std::tuple<Ts...>></code>.<ref>{{Cite web|title=std::execution::sync_wait|url=https://en.cppreference.com/w/cpp/thread/this_thread/sync_wait.html|publisher=cppreference.com|author=cppreference.com|access-date=15 February 2026|website=cppreference.com}}</ref>
It is worth noting that <code>std::promise</code> and <code>std::future</code>, although it would seem that they would be awaitable objects, implement none of the machinery required to be returned from coroutines and be awaited using <code>co_await</code>. Programmers must implement a number of public member functions, such as <code>await_ready</code>, <code>await_suspend</code>, and <code>await_resume</code> on the return type in order for the type to be awaited on. Details can be found on cppreference.<ref>{{cite web|url=https://en.cppreference.com/w/cpp/language/coroutines | title=Coroutines (C++20)}}</ref> <syntaxhighlight lang="c++"> import std;
using std::optional; using std::tuple; using std::execution::task;
task<int> add(int a, int b) noexcept { co_return a + b; }
task<int> test() { int ret = co_await add(1, 2); std::println("Return {}", ret); co_return ret; }
int main(int argc, char* argv[]) { optional<tuple<task<int>>> result = std::execution::sync_wait(test()); std::println("Result: {}", std::get<0>( result.value_or(std::make_tuple(-1))) );
return 0; } </syntaxhighlight>
=== C# === In 2012, C# added the async/await pattern in C# with version 5.0, which Microsoft refers to as the task-based asynchronous pattern (TAP).<ref>{{cite web |title=Task-based asynchronous pattern |url=https://docs.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap |publisher=Microsoft |accessdate=28 September 2020}}</ref> Async methods usually return either <code>void</code>, <code>Task</code>, <code>Task<T></code>,<ref name=Albahari/>{{rp|35}}<ref name=Price>{{cite book |last=Price | first=Mark J. |title=C# 8.0 and .NET Core 3.0 – Modern Cross-Platform Development: Build Applications with C#, .NET Core, Entity Framework Core, ASP.NET Core, and ML.NET Using Visual Studio Code | date=2022 | publisher= Packt |isbn= 978-1-098-12195-2}}</ref>{{rp|546-547}}<ref name=Skeet/>{{rp|22, 182}} <code>ValueTask</code> or <code>ValueTask<T></code>.<ref name=Albahari/>{{rp|651-652}}<ref name=Skeet/>{{rp|182-184}} User code can define custom types that async methods can return through custom ''async method builders'' but this is an advanced and rare scenario.<ref>{{Cite web |last=Tepliakov |first=Sergey |date=2018-01-11 |title=Extending the async methods in C# |url=https://devblogs.microsoft.com/premier-developer/extending-the-async-methods-in-c/ |access-date=2022-10-30 |website=Developer Support |language=en-US}}</ref> Async methods that return <code>void</code> are intended for [[event handler]]s; in most cases where a synchronous method would return <code>void</code>, returning <code>Task</code> instead is recommended, as it allows for more intuitive exception handling (note that <code>Task<void></code> is invalid in C#).<ref name="Cleary">Stephen Cleary, [https://msdn.microsoft.com/en-us/magazine/jj991977.aspx Async/Await - Best Practices in Asynchronous Programming]</ref>
Methods that make use of <code>await</code> must be declared with the <code>async</code> keyword. In methods that have a return value of type <code>Task<T></code>, methods declared with <code>async</code> must have a [[return statement]] of type assignable to <code>T</code> instead of <code>Task<T></code>; the compiler wraps the value in the <code>Task<T></code> generic. It is also possible to <code>await</code> methods that have a return type of <code>Task</code> or <code>Task<T></code> that are declared without <code>async</code>.
The following async method downloads data from a URL using <code>await</code>. Because this method issues a task for each URI before requiring completion with the <code>await</code> keyword, the resources can load at the same time instead of waiting for the last resource to finish before starting to load the next.
<syntaxhighlight lang="csharp"> namespace Wikipedia.Examples;
using System; using System.Collections.Generic; using System.Net.Http; using System.Threading.Tasks;
public class Example { public async Task<int> SumPageSizesAsync(IEnumerable<Uri> uris) { HttpClient client = new(); int total = 0; List<Task<byte[]>> loadUriTasks = new();
foreach (Uri uri in uris) { byte[] loadUriTask = client.GetByteArrayAsync(uri); loadUriTasks.Add(loadUriTask); }
foreach (Task<byte[]>> loadUriTask in loadUriTasks) { statusText.Text = $"Found {total} bytes ..."; byte[] resourceAsBytes = await loadUriTask; total += resourceAsBytes.Length; }
statusText.Text = $"Found {total} bytes total";
return total; }
static async Task Main(string[] args) { List<Uri> uris = new { new Uri("https://en.wikipedia.org"), new Uri("https://www.microsoft.com"), new Uri("https://www.github.com") }
int totalBytes = await SumPageSizesAsync(uris); Console.WriteLine($"Total bytes downloaded: {totalbytes}"); } } </syntaxhighlight>
=== F# === [[F Sharp (programming language)|In 2007, F#]] added asynchronous workflows with version 2.0.<ref>{{cite web|title=Introducing F# Asynchronous Workflows|date=10 October 2007 |url=https://blogs.msdn.microsoft.com/dsyme/2007/10/10/introducing-f-asynchronous-workflows/|publisher=}}</ref> The asynchronous workflows are implemented as CE ([[computation expressions]]). They can be defined without specifying any special context (like <code>async</code> in C#). [[F Sharp (programming language)|F#]] asynchronous workflows append a bang (!) to keywords to start asynchronous tasks.
The following async function downloads data from an URL using an asynchronous workflow: <syntaxhighlight lang="f#"> let asyncSumPageSizes (uris: #seq<Uri>) : Async<int> = async { use httpClient = new HttpClient() let! pages = uris |> Seq.map(httpClient.GetStringAsync >> Async.AwaitTask) |> Async.Parallel return pages |> Seq.fold (fun accumulator current -> current.Length + accumulator) 0 } </syntaxhighlight>
=== Java === Java does not have <code>async</code> and <code>await</code> keywords in the language, however it can be emulated using the <code>java.util.concurrent</code> package, such as the class <code>CompletableFuture</code> (introduced in Java 8). Asynchronous programming is later improved in Java 21 with the introduction of virtual threads and structured task scopes.
<syntaxhighlight lang="java"> package org.wikipedia.examples;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import static java.util.concurrent.StructuredTaskScope.ShutdownOnFailure; import static java.util.concurrent.StructuredTaskScope.Subtask;
public class AsyncExample { public String fetchData() { // Simulate a time-consuming operation (e.g., network request, database query) try { Thread.sleep(2000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } return "Data from remote source"; }
public CompletableFuture<String> fetchDataAsync() { return CompletableFuture.supplyAsync(() -> fetchData()); }
public static void main(String[] args) throws ExecutionException, InterruptedException { AsyncExample example = new AsyncExample();
// Using CompletableFuture (Java 8) System.out.println("Starting asynchronous operation...");
CompletableFuture<String> future = example.fetchDataAsync();
System.out.println("Doing other work...");
// Wait for the result (similar to 'await') String result = future.get(); System.out.printf("Received result: %s%n", result);
// Using Virtual Threads (Java 21): ExecutorService extor = Executors.newVirtualThreadPerTaskExecutor(); System.out.println("Starting virtual thread operation...");
Future<String> fut = extor.submit(() -> { return example.fetchData(); });
System.out.println("Doing other work...");
String result = future.get(); System.out.printf("Received result: %s%n", result); extor.shutdown();
// Using StructuredTaskScope (Java 21) try (ShutdownOnFailure scope = new ShutdownOnFailure()) { Subtask<String> dataTask = scope.fork(example::fetchData); System.out.println("Doing other work...");
scope.join(); // wait for all tasks scope.throwIfFailed(); // propagate if any exceptions
String result = future.get(); System.out.printf("Received result: %s%n", result); } } } </syntaxhighlight>
=== JavaScript ===
The await operator in JavaScript (and TypeScript) can only be used from inside an async function or at the top level of a [[Modular programming|module]]. If the parameter is a [[Futures and promises|promise]], execution of the async function will resume when the promise is resolved (unless the promise is rejected, in which case an error will be thrown that can be handled with normal JavaScript [[exception handling]]). If the parameter is not a promise, the parameter itself will be returned immediately.<ref>{{cite web|url=https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await|title=await - JavaScript (MDN)|accessdate=2 May 2017}}</ref>
Many libraries provide promise objects that can also be used with await, as long as they match the specification for native JavaScript promises. However, promises from the [[jQuery]] library were not Promises/A+ compatible until jQuery 3.0.<ref>{{cite web|url=https://jquery.com/upgrade-guide/3.0/#breaking-change-and-feature-jquery-deferred-is-now-promises-a-compatible|title=jQuery Core 3.0 Upgrade Guide|accessdate=2 May 2017}}</ref>
Below is an example (modified from this<ref name="JavaScript-async-await">{{cite web|url=http://pouchdb.com/2015/03/05/taming-the-async-beast-with-es7.html|title=Taming the asynchronous beast with ES7|accessdate=12 November 2015}}</ref> article):
<syntaxhighlight lang="typescript"> interface DBResponse { id: string; rev?: string; ok?: boolean; }
interface Document { _id: string; _rev?: string; [key: string]: any; }
interface Database { post(doc: object): Promise<DBResponse>; get(id: string): Promise<Document>; }
declare const db: Database;
async function createNewDoc(): Promise<Document> { const response: DBResponse = await db.post({}); const doc: Document = await db.get(response.id); return doc; }
async function main(): Promise<void> { try { const doc: Document = await createNewDoc(); console.log(doc); } catch (err: Error) { console.error("Error creating or fetching document:", err); } }
main(); </syntaxhighlight>
[[Node.js]] version 8 includes a utility that enables using the standard library callback-based methods as promises.<ref>{{cite web|url=https://nodejs.org/en/blog/release/v8.0.0/#improved-support-for-promises|title=Node v8.0.0 (Current) - Node.js|first=Node.js|last=Foundation|website=Node.js|date=30 May 2017 }}</ref>
=== Perl === The Future::AsyncAwait<ref>{{cite web|url=https://metacpan.org/pod/Future::AsyncAwait | title=Future::AsyncAwait - deferred subroutine syntax for futures}}</ref> module was the subject of a Perl Foundation grant in September 2018.<ref>{{Cite web|url=http://news.perlfoundation.org/2018/11/september-2018-grant-votes.html|title=September 2018 Grant Votes - The Perl Foundation|website=news.perlfoundation.org|access-date=2019-03-26}}</ref>
=== Python === Python 3.5 (2015)<ref>{{Cite web | url=https://www.python.org/downloads/release/python-350 | title=Python Release Python 3.5.0 }}</ref> has added support for async/await as described in PEP 492 (written and implemented by [[Yury Selivanov]]).<ref>{{Cite web | url=https://www.python.org/dev/peps/pep-0492/ | title=PEP 492 – Coroutines with async and await syntax }}</ref>
<syntaxhighlight lang="python"> import asyncio
async def main() -> None: print("hello") await asyncio.sleep(1) print("world")
if __name__ == "__main__": asyncio.run(main()) </syntaxhighlight>
=== Rust === On November 7, 2019, async/await was released on the stable version of Rust.<ref>{{cite web |last1=Matsakis |first1=Niko |title=Async-await on stable Rust! |url=https://blog.rust-lang.org/2019/11/07/Async-await-stable.html |website=Rust Blog |accessdate=7 November 2019}}</ref> Async functions in Rust [[Syntactic sugar|desugar]] to plain functions that return values that implement the Future trait. Currently they are implemented with a [[finite-state machine]].<ref>{{cite web |last1=Oppermann |first1=Philipp |title=Async/Await |url=https://os.phil-opp.com/async-await/#state-machine-transformation |accessdate=28 October 2020}}</ref>
<syntaxhighlight lang="rust"> // In the crate's Cargo.toml, we need `futures = "0.3.0"` in the dependencies section, // so we can use the futures crate
extern crate futures; // There is no executor currently in the `std` library.
use std::future::Future;
// This desugars to something like // `fn async_add_one(num: u32) -> impl Future<Output = u32>` async fn async_add_one(num: u32) -> u32 { num + 1 }
async fn example_task() -> impl Future<Output = ()> { let number = async_add_one(5).await; println!("5 + 1 = {}", number); }
fn main() { // Creating the Future does not start the execution. let future = example_task();
// The `Future` only executes when we actually poll it, unlike JavaScript. futures::executor::block_on(future); } </syntaxhighlight>
=== Swift === Swift 5.5 (2021)<ref>{{Cite web |url=https://www.swift.org/blog/swift-5-5-released/ |title=Archived copy |access-date=2021-12-20 |archive-date=2022-01-23 |archive-url=https://web.archive.org/web/20220123053303/https://www.swift.org/blog/swift-5-5-released/ |url-status=dead }}</ref> added support for async/await as described in SE-0296.<ref>{{cite web|url=https://github.com/apple/swift-evolution/blob/main/proposals/0296-async-await.md | title=SE-0296| website=[[GitHub]]}}</ref>
<syntaxhighlight lang="swift"> func getNumber() async throws -> Int { try await Task.sleep(nanoseconds: 1_000_000_000) return 42 }
Task { let first = try await getNumber() let second = try await getNumber() print(first + second) } </syntaxhighlight>
== Benefits and criticisms == {{anchor|Function coloring}} The async/await pattern is especially attractive to language designers of languages that do not have or control their own [[Runtime system|runtime]], as async/await can be implemented solely as a transformation to a [[state machine]] in the compiler.<ref>{{cite web | url=https://www.awise.us/2021/06/08/async-3.html | title=Async Part 3 - How the C# compiler implements async functions}}</ref>
Supporters claim that asynchronous, non-blocking code can be written with async/await that looks almost like traditional synchronous, blocking code. In particular, it has been argued that await is the best way of writing asynchronous code in [[Message passing|message-passing]] programs; in particular, being close to blocking code, readability and the minimal amount of [[boilerplate code]] were cited as await benefits.<ref>'No Bugs' Hare. [http://ithare.com/eight-ways-to-handle-non-blocking-returns-in-message-passing-programs-with-script/ Eight ways to handle non-blocking returns in message-passing programs] CPPCON, 2018</ref>
Critics of async/await note that the pattern tends to cause surrounding code to be asynchronous too; and that its contagious nature splits languages' library ecosystems between synchronous and asynchronous libraries and APIs, an issue often referred to as "function coloring".<ref>{{cite web |url=https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/ |title=What Color is Your Function?}}</ref> Alternatives to async/await that do not suffer from this issue are called "colorless". Examples of colorless designs include Go's [[goroutine]]s and Java's [[virtual thread]]s.<ref>{{cite web | url=https://docs.oracle.com/en/java/javase/21/core/virtual-threads.html |title=Virtual Threads}}</ref>
== See also == * [[Coroutines]] * [[Continuation-passing style]] * [[Direct style]] * [[Cooperative multitasking]] * [[Futures and promises]]
== References == {{reflist}}
[[Category:Control flow]]