CINXE.COM
Asynchronous programming: futures, async, await | Dart
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="x-ua-compatible" content="ie=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><script>!function(e,t,a,n){e[n]=e[n]||[],e[n].push({"gtm.start":(new Date).getTime(),event:"gtm.js"});var g=t.getElementsByTagName(a)[0],m=t.createElement(a);m.async=!0,m.src="https://www.googletagmanager.com/gtm.js?id=GTM-5VSZM5J",g.parentNode.insertBefore(m,g)}(window,document,"script","dataLayer")</script><meta name="description" content="Learn about and practice writing asynchronous code in DartPad!"><title>Asynchronous programming: futures, async, await | Dart</title><link rel="icon" sizes="64x64" href="/assets/img/logo/dart-64.png" eleventy:ignore><link href="/assets/img/touch-icon-iphone.png" rel="apple-touch-icon" eleventy:ignore><link href="/assets/img/touch-icon-ipad.png" rel="apple-touch-icon" sizes="152x152" eleventy:ignore><link href="/assets/img/touch-icon-iphone-retina.png" rel="apple-touch-icon" sizes="180x180" eleventy:ignore><link href="/assets/img/touch-icon-ipad-retina.png" rel="apple-touch-icon" sizes="167x167" eleventy:ignore><meta name="twitter:card" content="summary"><meta name="twitter:site" content="@dart_lang"><meta name="twitter:title" content="Asynchronous programming: futures, async, await"><meta name="twitter:description" content="Learn about and practice writing asynchronous code in DartPad!"><meta property="og:title" content="Asynchronous programming: futures, async, await"><meta property="og:description" content="Learn about and practice writing asynchronous code in DartPad!"><meta property="og:url" content="/libraries/async/async-await/"><meta property="og:image" content="/assets/img/logo/dart-logo-for-shares.png?2" eleventy:ignore><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Google+Sans:wght@400;500;700&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Google+Sans+Display:wght@400&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Google+Sans+Mono:wght@400;500;700&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Google+Sans+Text:wght@400;500;700&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0..1,0" rel="stylesheet"><link rel="stylesheet" href="/assets/css/main.css?v=3"><script src="/assets/js/os-tabs.js?v=3"></script><script src="/assets/js/main.js?v=3"></script><script defer="defer" src="/assets/js/inject_dartpad.js"></script><script>!function(e,a,t,n,c,o,s){e.GoogleAnalyticsObject=c,e[c]=e[c]||function(){(e[c].q=e[c].q||[]).push(arguments)},e[c].l=1*new Date,o=a.createElement(t),s=a.getElementsByTagName(t)[0],o.async=1,o.src="//www.google-analytics.com/analytics.js",s.parentNode.insertBefore(o,s)}(window,document,"script",0,"ga"),ga("create","UA-26406144-4","auto"),ga("send","pageview")</script></head><body class="default.html"><a id="skip-to-main" class="filled-button" href="#site-content-title" tabindex="1">Skip to main content</a><section id="cookie-notice"><div class="container"><p>dart.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic.</p><div class="button-group"><a class="text-button" href="https://policies.google.com/technologies/cookies" target="_blank" rel="noopener">Learn more</a> <button id="cookie-consent" class="filled-button">OK, got it</button></div></div></section><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5VSZM5J" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript><div id="site-banner" role="alert"><p>Announcing Dart 3.7! Find out about updates to the language, analyzer, pub.dev, and more, in the <a href="https://medium.com/dartlang/announcing-dart-3-7-bf864a1b195c" target="_blank">blog post</a>.</p></div><header id="site-header"><nav id="mainnav"><div id="menu-toggle"><span class="material-symbols" title="Toggle side navigation menu." aria-label="Toggle side navigation menu." type="button">menu</span></div><a href="/" class="brand" title="Dart"><img src="/assets/img/logo/logo-white-text.svg" alt="Dart"></a><ul class="navbar"><li><a href="/overview" class="nav-link">Overview</a></li><li class="mainnav__get-started"><a href="/docs" class="nav-link active"><span>Docs</span></a></li><li><a href="/community" class="nav-link">Community</a></li><li><a href="/#try-dart" class="nav-link">Try Dart</a></li><li><a href="/get-dart" class="nav-link">Get Dart</a></li><li class="searchfield"><form action="/search" class="site-header-search form-inline" id="cse-search-box"><input type="hidden" name="cx" value="011220921317074318178:_yy-tmb5t_i"> <input type="hidden" name="ie" value="UTF-8"> <input type="hidden" name="hl" value="en"> <input class="site-header-searchfield form-control search-field" type="search" name="q" id="search-main" autocomplete="off" placeholder="Search" aria-label="Search"></form></li></ul></nav></header><div id="site-below-header"><div id="site-main-row"><div id="sidenav"><form action="/search/" class="site-header-search form-inline"><input class="site-header-searchfield form-control search-field" type="search" name="q" id="search-side" autocomplete="off" placeholder="Search" aria-label="Search"></form><ul class="navbar-nav"><li aria-hidden="true"><div class="sidenav-divider"></div></li><li class="nav-item"><a href="/overview" class="nav-link">Overview</a></li><li class="nav-item"><a href="/community" class="nav-link">Community</a></li><li class="nav-item"><a href="https://dartpad.dev" class="nav-link">Try Dart</a></li><li class="nav-item"><a href="/get-dart" class="nav-link">Get Dart</a></li><li class="nav-item"><a href="/docs" class="nav-link">Docs</a></li><li aria-hidden="true"><div class="sidenav-divider"></div></li></ul><ul class="nav"><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-1" role="button" aria-expanded="false" aria-controls="-sidenav-1"><span>Language</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1"><li class="nav-item"><a class="nav-link" href="/language"><div><span>Introduction</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-2" role="button" aria-expanded="false" aria-controls="-sidenav-1-2"><span>Syntax basics</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-2"><li class="nav-item"><a class="nav-link" href="/language/variables"><div><span>Variables</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/operators"><div><span>Operators</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/comments"><div><span>Comments</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/metadata"><div><span>Metadata</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/libraries"><div><span>Libraries & imports</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/keywords"><div><span>Keywords</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-3" role="button" aria-expanded="false" aria-controls="-sidenav-1-3"><span>Types</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-3"><li class="nav-item"><a class="nav-link" href="/language/built-in-types"><div><span>Built-in types</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/records"><div><span>Records</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/collections"><div><span>Collections</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/generics"><div><span>Generics</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/typedefs"><div><span>Typedefs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/type-system"><div><span>Type system</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-4" role="button" aria-expanded="false" aria-controls="-sidenav-1-4"><span>Patterns</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-4"><li class="nav-item"><a class="nav-link" href="/language/patterns"><div><span>Overview & usage</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/pattern-types"><div><span>Pattern types</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/dart-patterns-records" target="_blank" rel="noopener"><div><span>Applied tutorial</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/language/functions"><div><span>Functions</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-6" role="button" aria-expanded="false" aria-controls="-sidenav-1-6"><span>Control flow</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-6"><li class="nav-item"><a class="nav-link" href="/language/loops"><div><span>Loops</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/branches"><div><span>Branches</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/error-handling"><div><span>Error handling</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-7" role="button" aria-expanded="false" aria-controls="-sidenav-1-7"><span>Classes & objects</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-7"><li class="nav-item"><a class="nav-link" href="/language/classes"><div><span>Classes</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/constructors"><div><span>Constructors</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/methods"><div><span>Methods</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/extend"><div><span>Extend a class</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/mixins"><div><span>Mixins</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/enums"><div><span>Enums</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/extension-methods"><div><span>Extension methods</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/extension-types"><div><span>Extension types</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/callable-objects"><div><span>Callable objects</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-8" role="button" aria-expanded="false" aria-controls="-sidenav-1-8"><span>Class modifiers</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-8"><li class="nav-item"><a class="nav-link" href="/language/class-modifiers"><div><span>Overview & usage</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/class-modifiers-for-apis"><div><span>Class modifiers for API maintainers</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/modifier-reference"><div><span>Reference</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-9" role="button" aria-expanded="false" aria-controls="-sidenav-1-9"><span>Concurrency</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-9"><li class="nav-item"><a class="nav-link" href="/language/concurrency"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/async"><div><span>Asynchronous support</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/isolates"><div><span>Isolates</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-10" role="button" aria-expanded="false" aria-controls="-sidenav-1-10"><span>Null safety</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-10"><li class="nav-item"><a class="nav-link" href="/null-safety"><div><span>Sound null safety</span></div></a></li><li class="nav-item"><a class="nav-link" href="/null-safety/migration-guide"><div><span>Migrating to null safety</span></div></a></li><li class="nav-item"><a class="nav-link" href="/null-safety/understanding-null-safety"><div><span>Understanding null safety</span></div></a></li><li class="nav-item"><a class="nav-link" href="/null-safety/unsound-null-safety"><div><span>Unsound null safety</span></div></a></li><li class="nav-item"><a class="nav-link" href="/null-safety/faq"><div><span>FAQ</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link active collapsible" data-toggle="collapse" data-target="#-sidenav-2" role="button" aria-expanded="true" aria-controls="-sidenav-2"><span>Core libraries</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="-sidenav-2"><li class="nav-item"><a class="nav-link" href="/libraries"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-core"><div><span>dart:core</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-async"><div><span>dart:async</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-math"><div><span>dart:math</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-convert"><div><span>dart:convert</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-io"><div><span>dart:io</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop"><div><span>dart:js_interop</span></div></a></li><div class="sidenav-divider"></div><li class="nav-item"><a class="nav-link" href="/libraries/collections/iterables"><div><span>Iterable collections</span></div></a></li><li class="nav-item"><button class="nav-link active collapsible" data-toggle="collapse" data-target="#-sidenav-2-10" role="button" aria-expanded="true" aria-controls="-sidenav-2-10"><span>Asynchronous programming</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="-sidenav-2-10"><li class="nav-item"><a class="nav-link active" href="/libraries/async/async-await"><div><span>Tutorial</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/async/futures-error-handling"><div><span>Futures and error handling</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/async/using-streams"><div><span>Using streams</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/async/creating-streams"><div><span>Creating streams</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-3" role="button" aria-expanded="false" aria-controls="-sidenav-3"><span>Effective Dart</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-3"><li class="nav-item"><a class="nav-link" href="/effective-dart"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/style"><div><span>Style</span></div></a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/documentation"><div><span>Documentation</span></div></a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/usage"><div><span>Usage</span></div></a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/design"><div><span>Design</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-4" role="button" aria-expanded="false" aria-controls="-sidenav-4"><span>Packages</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-4"><li class="nav-item"><a class="nav-link" href="/tools/pub/packages"><div><span>How to use packages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/useful-packages"><div><span>Commonly used packages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/create-packages"><div><span>Creating packages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/publishing"><div><span>Publishing packages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/writing-package-pages"><div><span>Writing package pages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/workspaces"><div><span>Workspaces (monorepo support)</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-4-7" role="button" aria-expanded="false" aria-controls="-sidenav-4-7"><span>Package reference</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-4-7"><li class="nav-item"><a class="nav-link" href="/tools/pub/dependencies"><div><span>Dependencies</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/glossary"><div><span>Glossary</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/package-layout"><div><span>Package layout conventions</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/environment-variables"><div><span>Pub environment variables</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/pubspec"><div><span>Pubspec file</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/troubleshoot"><div><span>Troubleshooting pub</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/verified-publishers"><div><span>Verified publishers</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/security-advisories"><div><span>Security advisories</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/versioning"><div><span>Versioning</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/custom-package-repositories"><div><span>Custom package repositories</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/tools/pub/private-files"><div><span>What not to commit</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-5" role="button" aria-expanded="false" aria-controls="-sidenav-5"><span>Development</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-5"><li class="nav-item"><a class="nav-link" href="/libraries/serialization/json"><div><span>JSON serialization</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/language/number-representation"><div><span>Number representation</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/google-apis"><div><span>Google APIs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/multiplatform-apps"><div><span>Multi-platform apps</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-5-5" role="button" aria-expanded="false" aria-controls="-sidenav-5-5"><span>Command-line & server apps</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-5-5"><li class="nav-item"><a class="nav-link" href="/server"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/get-started"><div><span>Get started</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/cmdline"><div><span>Write command-line apps</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/fetch-data"><div><span>Fetch data from the internet</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/httpserver"><div><span>Write HTTP servers</span></div></a></li><li class="nav-item"><a class="nav-link" href="/server/libraries"><div><span>Libraries & packages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/server/google-cloud"><div><span>Google Cloud</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-5-6" role="button" aria-expanded="false" aria-controls="-sidenav-5-6"><span>Web apps</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-5-6"><li class="nav-item"><a class="nav-link" href="/web"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/web/get-started"><div><span>Get started</span></div></a></li><li class="nav-item"><a class="nav-link" href="/web/deployment"><div><span>Deployment</span></div></a></li><li class="nav-item"><a class="nav-link" href="/web/libraries"><div><span>Libraries & packages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/web/wasm"><div><span>Wasm compilation</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/libraries/core/environment-declarations"><div><span>Environment declarations</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-6" role="button" aria-expanded="false" aria-controls="-sidenav-6"><span>Interoperability</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-6"><li class="nav-item"><a class="nav-link" href="/interop/c-interop"><div><span>C interop</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/objective-c-interop"><div><span>Objective-C & Swift interop</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/java-interop"><div><span>Java & Kotlin interop</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-6-4" role="button" aria-expanded="false" aria-controls="-sidenav-6-4"><span>JavaScript interop</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-6-4"><li class="nav-item"><a class="nav-link" href="/interop/js-interop"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop/usage"><div><span>Usage</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop/js-types"><div><span>JS types</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop/tutorials"><div><span>Tutorials</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop/past-js-interop"><div><span>Past JS interop</span></div></a></li><div class="sidenav-divider"></div><li class="nav-item"><a class="nav-link" href="/interop/js-interop/package-web"><div><span>Web interop</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-7" role="button" aria-expanded="false" aria-controls="-sidenav-7"><span>Tools & techniques</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-7"><li class="nav-item"><a class="nav-link" href="/tools"><div><span>Overview</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-7-2" role="button" aria-expanded="false" aria-controls="-sidenav-7-2"><span>Editors & debuggers</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-7-2"><li class="nav-item"><a class="nav-link" href="/tools/jetbrains-plugin"><div><span>IntelliJ & Android Studio</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/vs-code"><div><span>VS Code</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-devtools"><div><span>Dart DevTools</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-7-2-4" role="button" aria-expanded="false" aria-controls="-sidenav-7-2-4"><span>DartPad</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-7-2-4"><li class="nav-item"><a class="nav-link" href="/tools/dartpad"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dartpad/troubleshoot"><div><span>Troubleshooting DartPad</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-7-3" role="button" aria-expanded="false" aria-controls="-sidenav-7-3"><span>Command-line tools</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-7-3"><li class="nav-item"><button class="nav-link collapsible" data-toggle="collapse" data-target="#-sidenav-7-3-1" role="button" aria-expanded="true" aria-controls="-sidenav-7-3-1"><span>Dart SDK</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="-sidenav-7-3-1"><li class="nav-item"><a class="nav-link" href="/tools/sdk"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-tool"><div><span>dart</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-analyze"><div><span>dart analyze</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-compile"><div><span>dart compile</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-create"><div><span>dart create</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-doc"><div><span>dart doc</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-fix"><div><span>dart fix</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-format"><div><span>dart format</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-info"><div><span>dart info</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/cmd"><div><span>dart pub</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-run"><div><span>dart run</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-test"><div><span>dart test</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dartaotruntime"><div><span>dartaotruntime</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/experiment-flags"><div><span>Experiment flags</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible" data-toggle="collapse" data-target="#-sidenav-7-3-2" role="button" aria-expanded="true" aria-controls="-sidenav-7-3-2"><span>Other command-line tools</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="-sidenav-7-3-2"><li class="nav-item"><a class="nav-link" href="/tools/build_runner"><div><span>build_runner</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/webdev"><div><span>webdev</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-7-4" role="button" aria-expanded="false" aria-controls="-sidenav-7-4"><span>Static analysis</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-7-4"><li class="nav-item"><a class="nav-link" href="/tools/analysis"><div><span>Customizing static analysis</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/non-promotion-reasons"><div><span>Fixing type promotion failures</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/linter-rules"><div><span>Linter rules</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/diagnostic-messages"><div><span>Diagnostic messages</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-7-5" role="button" aria-expanded="false" aria-controls="-sidenav-7-5"><span>Testing & optimization</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-7-5"><li class="nav-item"><a class="nav-link" href="/tools/testing"><div><span>Testing</span></div></a></li><li class="nav-item"><a class="nav-link" href="/web/debugging"><div><span>Debugging web apps</span></div></a></li></ul></li></ul></li><li aria-hidden="true"><div class="sidenav-divider"></div></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-9" role="button" aria-expanded="false" aria-controls="-sidenav-9"><span>Resources</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-9"><li class="nav-item"><a class="nav-link" href="/resources/dart-cheatsheet"><div><span>Language cheatsheet</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/breaking-changes"><div><span>Breaking changes</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/language/evolution"><div><span>Language evolution</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/language/spec"><div><span>Language specification</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/dart-3-migration"><div><span>Dart 3 migration guide</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-9-6" role="button" aria-expanded="false" aria-controls="-sidenav-9-6"><span>Coming from ...</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-9-6"><li class="nav-item"><a class="nav-link" href="/resources/coming-from/js-to-dart"><div><span>JavaScript to Dart</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/coming-from/swift-to-dart"><div><span>Swift to Dart</span></div></a></li></ul></li><div class="sidenav-divider"></div><li class="nav-item"><a class="nav-link" href="/resources/faq"><div><span>FAQ</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/glossary"><div><span>Glossary</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/books"><div><span>Books</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/videos"><div><span>Videos</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tutorials"><div><span>Tutorials</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible" data-toggle="collapse" data-target="#-sidenav-10" role="button" aria-expanded="true" aria-controls="-sidenav-10"><span>Related sites</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="-sidenav-10"><li class="nav-item"><a class="nav-link" href="https://api.dart.dev" target="_blank" rel="noopener"><div><span>API reference</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://medium.com/dartlang" target="_blank" rel="noopener"><div><span>Blog</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://dartpad.dev" target="_blank" rel="noopener"><div><span>DartPad (online editor)</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://flutter.dev" target="_blank" rel="noopener"><div><span>Flutter</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev" target="_blank" rel="noopener"><div><span>Package site</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li></ul></div><main id="page-content"><div id="site-toc--side" class="site-toc"><header class="site-toc__title">Contents</header><ul class="section-nav"><li class="toc-entry nav-item"><a class="nav-link" href="#why-asynchronous-code-matters">Why asynchronous code matters</a><ul class="nav"><li class="toc-entry nav-item"><a class="nav-link" href="#example-incorrectly-using-an-asynchronous-function">Example: Incorrectly using an asynchronous function</a></li></ul></li><li class="toc-entry nav-item"><a class="nav-link" href="#what-is-a-future">What is a future?</a><ul class="nav"><li class="toc-entry nav-item"><a class="nav-link" href="#uncompleted">Uncompleted</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#completed">Completed</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#example-introducing-futures">Example: Introducing futures</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#example-completing-with-an-error">Example: Completing with an error</a></li></ul></li><li class="toc-entry nav-item"><a class="nav-link" href="#working-with-futures-async-and-await">Working with futures: async and await</a><ul class="nav"><li class="toc-entry nav-item"><a class="nav-link" href="#execution-flow-with-async-and-await">Execution flow with async and await</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#example-execution-within-async-functions">Example: Execution within async functions</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#exercise-practice-using-async-and-await">Exercise: Practice using async and await</a></li></ul></li><li class="toc-entry nav-item"><a class="nav-link" href="#handling-errors">Handling errors</a><ul class="nav"><li class="toc-entry nav-item"><a class="nav-link" href="#example-async-and-await-with-try-catch">Example: async and await with try-catch</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#exercise-practice-handling-errors">Exercise: Practice handling errors</a></li></ul></li><li class="toc-entry nav-item"><a class="nav-link" href="#exercise-putting-it-all-together">Exercise: Putting it all together</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#which-lints-work-for-futures">Which lints work for futures?</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#whats-next">What's next?</a></li></ul></div><article><div class="content"><div id="site-content-title"><h1>Asynchronous programming: futures, async, await</h1></div><div id="site-toc--inline" class="site-toc toc-collapsible toc-collapsed"><header class="site-toc__title">Contents <span class="site-toc--inline__toggle toc-toggle-down"><i class="material-symbols">keyboard_arrow_down</i></span> <span class="site-toc--inline__toggle toc-toggle-up"><i class="material-symbols">keyboard_arrow_up</i></span></header><ul class="section-nav"><li class="toc-entry"><a href="#why-asynchronous-code-matters">Why asynchronous code matters</a><ul><li class="toc-entry"><a href="#example-incorrectly-using-an-asynchronous-function">Example: Incorrectly using an asynchronous function</a></li></ul></li><li class="toc-entry"><a href="#what-is-a-future">What is a future?</a><ul><li class="toc-entry"><a href="#uncompleted">Uncompleted</a></li><li class="toc-entry"><a href="#completed">Completed</a></li><li class="toc-entry"><a href="#example-introducing-futures">Example: Introducing futures</a></li><li class="toc-entry"><a href="#example-completing-with-an-error">Example: Completing with an error</a></li></ul></li><li class="toc-entry"><a href="#working-with-futures-async-and-await">Working with futures: async and await</a><ul><li class="toc-entry"><a href="#execution-flow-with-async-and-await">Execution flow with async and await</a></li><li class="toc-entry"><a href="#example-execution-within-async-functions">Example: Execution within async functions</a></li><li class="toc-entry"><a href="#exercise-practice-using-async-and-await">Exercise: Practice using async and await</a></li></ul></li><li class="toc-entry"><a href="#handling-errors">Handling errors</a><ul><li class="toc-entry"><a href="#example-async-and-await-with-try-catch">Example: async and await with try-catch</a></li><li class="toc-entry"><a href="#exercise-practice-handling-errors">Exercise: Practice handling errors</a></li></ul></li><li class="toc-entry"><a href="#exercise-putting-it-all-together">Exercise: Putting it all together</a></li><li class="toc-entry"><a href="#which-lints-work-for-futures">Which lints work for futures?</a></li><li class="toc-entry"><a href="#whats-next">What's next?</a></li></ul><span class="site-toc--inline__toggle toc-toggle-more-items"><i class="material-symbols">more_horiz</i></span></div> <?code-excerpt replace="/ *\/\/\s+ignore_for_file:[^\n]+\n//g; /(^|\n) *\/\/\s+ignore:[^\n]+\n/$1/g; /(\n[^\n]+) *\/\/\s+ignore:[^\n]+\n/$1\n/g"?> <?code-excerpt plaster="none"?> <p>This tutorial teaches you how to write asynchronous code using futures and the <code>async</code> and <code>await</code> keywords. Using embedded DartPad editors, you can test your knowledge by running example code and completing exercises.</p><p>To get the most out of this tutorial, you should have the following:</p><ul><li>Knowledge of <a href="/language">basic Dart syntax</a>.</li><li>Some experience writing asynchronous code in another language.</li><li>The <a href="/tools/linter-rules/discarded_futures"><code>discarded_futures</code></a> and <a href="/tools/linter-rules/unawaited_futures"><code>unawaited_futures</code></a> lints enabled.</li></ul><p>This tutorial covers the following material:</p><ul><li>How and when to use the <code>async</code> and <code>await</code> keywords.</li><li>How using <code>async</code> and <code>await</code> affects execution order.</li><li>How to handle errors from an asynchronous call using <code>try-catch</code> expressions in <code>async</code> functions.</li></ul><p>Estimated time to complete this tutorial: 40-60 minutes.</p><aside class="alert alert-info"><div class="alert-header"><span class="material-symbols" aria-hidden="true">info</span> <span>Note</span></div><div class="alert-content"><p>This page uses embedded DartPads to display examples and exercises. If you see empty boxes instead of DartPads, go to the <a href="/tools/dartpad/troubleshoot">DartPad troubleshooting page</a>.</p></div></aside><p>The exercises in this tutorial have partially completed code snippets. You can use DartPad to test your knowledge by completing the code and clicking the <strong>Run</strong> button. <strong>Don't edit the test code in the <code>main</code> function or below</strong>.</p><p>If you need help, expand the <strong>Hint</strong> or <strong>Solution</strong> dropdown after each exercise.</p><div class="header-wrapper"><h2 id="why-asynchronous-code-matters">Why asynchronous code matters</h2><a class="heading-link" href="#why-asynchronous-code-matters" aria-label="Link to 'Why asynchronous code matters' section">#</a></div><p>Asynchronous operations let your program complete work while waiting for another operation to finish. Here are some common asynchronous operations:</p><ul><li>Fetching data over a network.</li><li>Writing to a database.</li><li>Reading data from a file.</li></ul><p>Such asynchronous computations usually provide their result as a <code>Future</code> or, if the result has multiple parts, as a <code>Stream</code>. These computations introduce asynchrony into a program. To accommodate that initial asynchrony, other plain Dart functions also need to become asynchronous.</p><p>To interact with these asynchronous results, you can use the <code>async</code> and <code>await</code> keywords. Most asynchronous functions are just async Dart functions that depend, possibly deep down, on an inherently asynchronous computation.</p><div class="header-wrapper"><h3 id="example-incorrectly-using-an-asynchronous-function">Example: Incorrectly using an asynchronous function</h3><a class="heading-link" href="#example-incorrectly-using-an-asynchronous-function" aria-label="Link to 'Example: Incorrectly using an asynchronous function' section">#</a></div><p>The following example shows the wrong way to use an asynchronous function (<code>fetchUserOrder()</code>). Later you'll fix the example using <code>async</code> and <code>await</code>. Before running this example, try to spot the issue -- what do you think the output will be?</p> <?code-excerpt "async_await/bin/get_order_sync_bad.dart" remove="Fetching"?> <pre><code data-dartpad="true" data-embed="true" data-theme="light" title="Runnable Dart sample" data-run="false">// This example shows how *not* to write asynchronous Dart code. String createOrderMessage() { var order = fetchUserOrder(); return 'Your order is: $order'; } Future<String> fetchUserOrder() => // Imagine that this function is more complex and slow. Future.delayed(const Duration(seconds: 2), () => 'Large Latte'); void main() { print(createOrderMessage()); } </code></pre><p>Here's why the example fails to print the value that <code>fetchUserOrder()</code> eventually produces:</p><ul><li><code>fetchUserOrder()</code> is an asynchronous function that, after a delay, provides a string that describes the user's order: a "Large Latte".</li><li>To get the user's order, <code>createOrderMessage()</code> should call <code>fetchUserOrder()</code> and wait for it to finish. Because <code>createOrderMessage()</code> does <em>not</em> wait for <code>fetchUserOrder()</code> to finish, <code>createOrderMessage()</code> fails to get the string value that <code>fetchUserOrder()</code> eventually provides.</li><li>Instead, <code>createOrderMessage()</code> gets a representation of pending work to be done: an uncompleted future. You'll learn more about futures in the next section.</li><li>Because <code>createOrderMessage()</code> fails to get the value describing the user's order, the example fails to print "Large Latte" to the console, and instead prints "Your order is: Instance of '_Future<String>'".</li></ul><p>In the next sections you'll learn about futures and about working with futures (using <code>async</code> and <code>await</code>) so that you'll be able to write the code necessary to make <code>fetchUserOrder()</code> print the desired value ("Large Latte") to the console.</p><aside class="alert alert-secondary"><div class="alert-header"><span>Key terms</span></div><div class="alert-content"><ul><li><strong>synchronous operation</strong>: A synchronous operation blocks other operations from executing until it completes.</li><li><strong>synchronous function</strong>: A synchronous function only performs synchronous operations.</li><li><strong>asynchronous operation</strong>: Once initiated, an asynchronous operation allows other operations to execute before it completes.</li><li><strong>asynchronous function</strong>: An asynchronous function performs at least one asynchronous operation and can also perform <em>synchronous</em> operations.</li></ul></div></aside><div class="header-wrapper"><h2 id="what-is-a-future">What is a future?</h2><a class="heading-link" href="#what-is-a-future" aria-label="Link to 'What is a future?' section">#</a></div><p>A future (lower case "f") is an instance of the <a href="https://api.dart.dev/dart-async/Future-class.html">Future</a> (capitalized "F") class. A future represents the result of an asynchronous operation, and can have two states: uncompleted or completed.</p><aside class="alert alert-info"><div class="alert-header"><span class="material-symbols" aria-hidden="true">info</span> <span>Note</span></div><div class="alert-content"><p><em>Uncompleted</em> is a Dart term referring to the state of a future before it has produced a value.</p></div></aside><div class="header-wrapper"><h3 id="uncompleted">Uncompleted</h3><a class="heading-link" href="#uncompleted" aria-label="Link to 'Uncompleted' section">#</a></div><p>When you call an asynchronous function, it returns an uncompleted future. That future is waiting for the function's asynchronous operation to finish or to throw an error.</p><div class="header-wrapper"><h3 id="completed">Completed</h3><a class="heading-link" href="#completed" aria-label="Link to 'Completed' section">#</a></div><p>If the asynchronous operation succeeds, the future completes with a value. Otherwise, it completes with an error.</p><div class="header-wrapper"><h4 id="completing-with-a-value">Completing with a value</h4><a class="heading-link" href="#completing-with-a-value" aria-label="Link to 'Completing with a value' section">#</a></div><p>A future of type <code>Future<T></code> completes with a value of type <code>T</code>. For example, a future with type <code>Future<String></code> produces a string value. If a future doesn't produce a usable value, then the future's type is <code>Future<void></code>.</p><div class="header-wrapper"><h4 id="completing-with-an-error">Completing with an error</h4><a class="heading-link" href="#completing-with-an-error" aria-label="Link to 'Completing with an error' section">#</a></div><p>If the asynchronous operation performed by the function fails for any reason, the future completes with an error.</p><div class="header-wrapper"><h3 id="example-introducing-futures">Example: Introducing futures</h3><a class="heading-link" href="#example-introducing-futures" aria-label="Link to 'Example: Introducing futures' section">#</a></div><p>In the following example, <code>fetchUserOrder()</code> returns a future that completes after printing to the console. Because it doesn't return a usable value, <code>fetchUserOrder()</code> has the type <code>Future<void></code>. Before you run the example, try to predict which will print first: "Large Latte" or "Fetching user order...".</p> <?code-excerpt "async_await/bin/futures_intro.dart (no-error)"?> <pre><code data-dartpad="true" data-embed="true" data-theme="light" title="Runnable Dart sample" data-run="false">Future<void> fetchUserOrder() { // Imagine that this function is fetching user info from another service or database. return Future.delayed(const Duration(seconds: 2), () => print('Large Latte')); } void main() { fetchUserOrder(); print('Fetching user order...'); } </code></pre><p>In the preceding example, even though <code>fetchUserOrder()</code> executes before the <code>print()</code> call on line 8, the console shows the output from line 8("Fetching user order...") before the output from <code>fetchUserOrder()</code> ("Large Latte"). This is because <code>fetchUserOrder()</code> delays before it prints "Large Latte".</p><div class="header-wrapper"><h3 id="example-completing-with-an-error">Example: Completing with an error</h3><a class="heading-link" href="#example-completing-with-an-error" aria-label="Link to 'Example: Completing with an error' section">#</a></div><p>Run the following example to see how a future completes with an error. A bit later you'll learn how to handle the error.</p> <?code-excerpt "async_await/bin/futures_intro.dart (error)" replace="/Error//g"?> <pre><code data-dartpad="true" data-embed="true" data-theme="light" title="Runnable Dart sample" data-run="false">Future<void> fetchUserOrder() { // Imagine that this function is fetching user info but encounters a bug. return Future.delayed( const Duration(seconds: 2), () => throw Exception('Logout failed: user ID is invalid'), ); } void main() { fetchUserOrder(); print('Fetching user order...'); } </code></pre><p>In this example, <code>fetchUserOrder()</code> completes with an error indicating that the user ID is invalid.</p><p>You've learned about futures and how they complete, but how do you use the results of asynchronous functions? In the next section you'll learn how to get results with the <code>async</code> and <code>await</code> keywords.</p><aside class="alert alert-secondary"><div class="alert-header"><span>Quick review</span></div><div class="alert-content"><ul><li>A <a href="https://api.dart.dev/dart-async/Future-class.html">Future<T></a> instance produces a value of type <code>T</code>.</li><li>If a future doesn't produce a usable value, then the future's type is <code>Future<void></code>.</li><li>A future can be in one of two states: uncompleted or completed.</li><li>When you call a function that returns a future, the function queues up work to be done and returns an uncompleted future.</li><li>When a future's operation finishes, the future completes with a value or with an error.</li></ul><p><strong>Key terms:</strong></p><ul><li><strong>Future</strong>: the Dart <a href="https://api.dart.dev/dart-async/Future-class.html">Future</a> class.</li><li><strong>future</strong>: an instance of the Dart <code>Future</code> class.</li></ul></div></aside><div class="header-wrapper"><h2 id="working-with-futures-async-and-await">Working with futures: async and await</h2><a class="heading-link" href="#working-with-futures-async-and-await" aria-label="Link to 'Working with futures: async and await' section">#</a></div><p>The <code>async</code> and <code>await</code> keywords provide a declarative way to define asynchronous functions and use their results. Remember these two basic guidelines when using <code>async</code> and <code>await</code>:</p><ul><li><strong>To define an async function, add <code>async</code> before the function body:</strong></li><li><strong>The <code>await</code> keyword works only in <code>async</code> functions.</strong></li></ul><p>Here's an example that converts <code>main()</code> from a synchronous to asynchronous function.</p><p>First, add the <code>async</code> keyword before the function body:</p> <?code-excerpt "async_await/bin/get_order_sync_bad.dart (main-sig)" replace="/main\(\)/$& async/g; /async/[!$&!]/g; /$/ 路路路 }/g"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() </span><mark class="highlight"><span style="color:#D43324">async</span></mark><span style="color:#222222"> { 路路路 }</span></span></code></pre></div></div><p>If the function has a declared return type, then update the type to be <code>Future<T></code>, where <code>T</code> is the type of the value that the function returns. If the function doesn't explicitly return a value, then the return type is <code>Future<void></code>:</p> <?code-excerpt "async_await/bin/get_order.dart (main-sig)" replace="/Future<\w+\W/[!$&!]/g; /$/ 路路路 }/g"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><mark class="highlight"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#D43324">void</span><span style="color:#222222">></span></mark><span style="color:#222222"> </span><span style="color:#6200EE">main</span><span style="color:#222222">() </span><span style="color:#D43324">async</span><span style="color:#222222"> { 路路路 }</span></span></code></pre></div></div><p>Now that you have an <code>async</code> function, you can use the <code>await</code> keyword to wait for a future to complete:</p> <?code-excerpt "async_await/bin/get_order.dart (print-order)" replace="/await/[!$&!]/g"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#6200EE">print</span><span style="color:#222222">(</span><mark class="highlight"><span style="color:#D43324">await</span></mark><span style="color:#6200EE"> createOrderMessage</span><span style="color:#222222">());</span></span></code></pre></div></div><p>As the following two examples show, the <code>async</code> and <code>await</code> keywords result in asynchronous code that looks a lot like synchronous code. The only differences are highlighted in the asynchronous example, which鈥攊f your window is wide enough鈥攊s to the right of the synchronous example.</p><div class="header-wrapper"><h4 id="example-synchronous-functions">Example: synchronous functions</h4><a class="heading-link" href="#example-synchronous-functions" aria-label="Link to 'Example: synchronous functions' section">#</a></div> <?code-excerpt "async_await/bin/get_order_sync_bad.dart (no-warning)" replace="/(\s+\/\/ )(Imagine.*? is )(.*)/$1$2$1$3/g"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">String</span><span style="color:#6200EE"> createOrderMessage</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> order = </span><span style="color:#6200EE">fetchUserOrder</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#11796D"> 'Your order is: </span><span style="color:#11796D">$</span><span style="color:#222222">order</span><span style="color:#11796D">'</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#222222">}</span></span> <span class="line"></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">String</span><span style="color:#222222">> </span><span style="color:#6200EE">fetchUserOrder</span><span style="color:#222222">() =></span></span> <span class="line"><span style="color:#6E6E70">// Imagine that this function is</span></span> <span class="line"><span style="color:#6E6E70">// more complex and slow.</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222">.</span><span style="color:#6200EE">delayed</span><span style="color:#222222">(</span><span style="color:#D43324">const</span><span style="color:#0468D7"> Duration</span><span style="color:#222222">(seconds: </span><span style="color:#11796D">2</span><span style="color:#222222">), () => </span><span style="color:#11796D">'Large Latte'</span><span style="color:#222222">);</span></span> <span class="line"></span> <span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> print</span><span style="color:#222222">(</span><span style="color:#11796D">'Fetching user order...'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#6200EE"> print</span><span style="color:#222222">(</span><span style="color:#6200EE">createOrderMessage</span><span style="color:#222222">());</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="code-block-wrapper language-plaintext"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span>Fetching user order...</span></span> <span class="line"><span>Your order is: Instance of 'Future<String>'</span></span></code></pre></div></div><p>As shown in following two examples, it operates like synchronous code.</p><div class="header-wrapper"><h4 id="example-asynchronous-functions">Example: asynchronous functions</h4><a class="heading-link" href="#example-asynchronous-functions" aria-label="Link to 'Example: asynchronous functions' section">#</a></div> <?code-excerpt "async_await/bin/get_order.dart" replace="/(\s+\/\/ )(Imagine.*? is )(.*)/$1$2$1$3/g; /async|await/[!$&!]/g; /(Future<\w+\W)( [^f])/[!$1!]$2/g; /4/2/g"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><mark class="highlight"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">String</span><span style="color:#222222">></span></mark><span style="color:#222222"> </span><span style="color:#6200EE">createOrderMessage</span><span style="color:#222222">() </span><mark class="highlight"><span style="color:#D43324">async</span></mark><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> order = </span><mark class="highlight"><span style="color:#D43324">await</span></mark><span style="color:#6200EE"> fetchUserOrder</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#11796D"> 'Your order is: </span><span style="color:#11796D">$</span><span style="color:#222222">order</span><span style="color:#11796D">'</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#222222">}</span></span> <span class="line"></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">String</span><span style="color:#222222">> </span><span style="color:#6200EE">fetchUserOrder</span><span style="color:#222222">() =></span></span> <span class="line"><span style="color:#6E6E70">// Imagine that this function is</span></span> <span class="line"><span style="color:#6E6E70">// more complex and slow.</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222">.</span><span style="color:#6200EE">delayed</span><span style="color:#222222">(</span><span style="color:#D43324">const</span><span style="color:#0468D7"> Duration</span><span style="color:#222222">(seconds: </span><span style="color:#11796D">2</span><span style="color:#222222">), () => </span><span style="color:#11796D">'Large Latte'</span><span style="color:#222222">);</span></span> <span class="line"></span> <span class="line"><mark class="highlight"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#D43324">void</span><span style="color:#222222">></span></mark><span style="color:#222222"> </span><span style="color:#6200EE">main</span><span style="color:#222222">() </span><mark class="highlight"><span style="color:#D43324">async</span></mark><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#6200EE"> print</span><span style="color:#222222">(</span><span style="color:#11796D">'Fetching user order...'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#6200EE"> print</span><span style="color:#222222">(</span><mark class="highlight"><span style="color:#D43324">await</span></mark><span style="color:#6200EE"> createOrderMessage</span><span style="color:#222222">());</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="code-block-wrapper language-plaintext"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span>Fetching user order...</span></span> <span class="line"><span>Your order is: Large Latte</span></span></code></pre></div></div><p>The asynchronous example is different in three ways:</p><ul><li>The return type for <code>createOrderMessage()</code> changes from <code>String</code> to <code>Future<String></code>.</li><li>The <strong><code>async</code></strong> keyword appears before the function bodies for <code>createOrderMessage()</code> and <code>main()</code>.</li><li>The <strong><code>await</code></strong> keyword appears before calling the asynchronous functions <code>fetchUserOrder()</code> and <code>createOrderMessage()</code>.</li></ul><aside class="alert alert-secondary"><div class="alert-header"><span>Key terms</span></div><div class="alert-content"><ul><li><strong>async</strong>: You can use the <code>async</code> keyword before a function's body to mark it as asynchronous.</li><li><strong>async function</strong>: An <code>async</code> function is a function labeled with the <code>async</code> keyword.</li><li><strong>await</strong>: You can use the <code>await</code> keyword to get the completed result of an asynchronous expression. The <code>await</code> keyword only works within an <code>async</code> function.</li></ul></div></aside><div class="header-wrapper"><h3 id="execution-flow-with-async-and-await">Execution flow with async and await</h3><a class="heading-link" href="#execution-flow-with-async-and-await" aria-label="Link to 'Execution flow with async and await' section">#</a></div><p>An <code>async</code> function runs synchronously until the first <code>await</code> keyword. This means that within an <code>async</code> function body, all synchronous code before the first <code>await</code> keyword executes immediately.</p><div class="header-wrapper"><h3 id="example-execution-within-async-functions">Example: Execution within async functions</h3><a class="heading-link" href="#example-execution-within-async-functions" aria-label="Link to 'Example: Execution within async functions' section">#</a></div><p>Run the following example to see how execution proceeds within an <code>async</code> function body. What do you think the output will be?</p> <?code-excerpt "async_await/bin/async_example.dart" remove="/\/\/ print/"?> <pre><code data-dartpad="true" data-embed="true" data-theme="light" title="Runnable Dart sample" data-run="false">Future<void> printOrderMessage() async { print('Awaiting user order...'); var order = await fetchUserOrder(); print('Your order is: $order'); } Future<String> fetchUserOrder() { // Imagine that this function is more complex and slow. return Future.delayed(const Duration(seconds: 4), () => 'Large Latte'); } void main() async { countSeconds(4); await printOrderMessage(); } // You can ignore this function - it's here to visualize delay time in this example. void countSeconds(int s) { for (var i = 1; i <= s; i++) { Future.delayed(Duration(seconds: i), () => print(i)); } } </code></pre><p>After running the code in the preceding example, try reversing lines 2 and 3:</p> <?code-excerpt "async_await/bin/async_example.dart (swap-stmts)" replace="/\/\/ (print)/$1/g"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">var</span><span style="color:#222222"> order = </span><span style="color:#D43324">await</span><span style="color:#6200EE"> fetchUserOrder</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#6200EE">print</span><span style="color:#222222">(</span><span style="color:#11796D">'Awaiting user order...'</span><span style="color:#222222">);</span></span></code></pre></div></div><p>Notice that timing of the output shifts, now that <code>print('Awaiting user order')</code> appears after the first <code>await</code> keyword in <code>printOrderMessage()</code>.</p><div class="header-wrapper"><h3 id="exercise-practice-using-async-and-await">Exercise: Practice using async and await</h3><a class="heading-link" href="#exercise-practice-using-async-and-await" aria-label="Link to 'Exercise: Practice using async and await' section">#</a></div><p>The following exercise is a failing unit test that contains partially completed code snippets. Your task is to complete the exercise by writing code to make the tests pass. You don't need to implement <code>main()</code>.</p><p>To simulate asynchronous operations, call the following functions, which are provided for you:</p><div class="table-wrapper"><table class="table table-striped"><thead><tr><th>Function</th><th>Type signature</th><th>Description</th></tr></thead><tbody><tr><td>fetchRole()</td><td><code>Future<String> fetchRole()</code></td><td>Gets a short description of the user's role.</td></tr><tr><td>fetchLoginAmount()</td><td><code>Future<int> fetchLoginAmount()</code></td><td>Gets the number of times a user has logged in.</td></tr></tbody></table></div><div class="header-wrapper"><h4 id="part-1-reportuserrole">Part 1: <code>reportUserRole()</code></h4><a class="heading-link" href="#part-1-reportuserrole" aria-label="Link to 'Part 1: reportUserRole()' section">#</a></div><p>Add code to the <code>reportUserRole()</code> function so that it does the following:</p><ul><li>Returns a future that completes with the following string: <code>"User role: <user role>"</code><ul><li>Note: You must use the actual value returned by <code>fetchRole()</code>; copying and pasting the example return value won't make the test pass.</li><li>Example return value: <code>"User role: tester"</code></li></ul></li><li>Gets the user role by calling the provided function <code>fetchRole()</code>.</li></ul><div class="header-wrapper"><h4 id="part-2-reportlogins">Part 2: <code>reportLogins()</code></h4><a class="heading-link" href="#part-2-reportlogins" aria-label="Link to 'Part 2: reportLogins()' section">#</a></div><p>Implement an <code>async</code> function <code>reportLogins()</code> so that it does the following:</p><ul><li>Returns the string <code>"Total number of logins: <# of logins>"</code>.<ul><li>Note: You must use the actual value returned by <code>fetchLoginAmount()</code>; copying and pasting the example return value won't make the test pass.</li><li>Example return value from <code>reportLogins()</code>: <code>"Total number of logins: 57"</code></li></ul></li><li>Gets the number of logins by calling the provided function <code>fetchLoginAmount()</code>.</li></ul><pre><code data-dartpad="true" data-embed="true" data-theme="dark" title="Runnable Dart sample" data-run="false">// Part 1 // Call the provided async function fetchRole() // to return the user role. Future<String> reportUserRole() async { // TODO: Implement the reportUserRole function here. } // Part 2 // TODO: Implement the reportLogins function here. // Call the provided async function fetchLoginAmount() // to return the number of times that the user has logged in. reportLogins() {} // The following functions those provided to you to simulate // asynchronous operations that could take a while. Future<String> fetchRole() => Future.delayed(_halfSecond, () => _role); Future<int> fetchLoginAmount() => Future.delayed(_halfSecond, () => _logins); // The following code is used to test and provide feedback on your solution. // There is no need to read or modify it. void main() async { print('Testing...'); List<String> messages = []; const passed = 'PASSED'; const testFailedMessage = 'Test failed for the function:'; const typoMessage = 'Test failed! Check for typos in your return value'; try { messages ..add(_makeReadable( testLabel: 'Part 1', testResult: await _asyncEquals( expected: 'User role: administrator', actual: await reportUserRole(), typoKeyword: _role, ), readableErrors: { typoMessage: typoMessage, 'null': 'Test failed! Did you forget to implement or return from reportUserRole?', 'User role: Instance of \'Future<String>\'': '$testFailedMessage reportUserRole. Did you use the await keyword?', 'User role: Instance of \'_Future<String>\'': '$testFailedMessage reportUserRole. Did you use the await keyword?', 'User role:': '$testFailedMessage reportUserRole. Did you return a user role?', 'User role: ': '$testFailedMessage reportUserRole. Did you return a user role?', 'User role: tester': '$testFailedMessage reportUserRole. Did you invoke fetchRole to fetch the user\'s role?', })) ..add(_makeReadable( testLabel: 'Part 2', testResult: await _asyncEquals( expected: 'Total number of logins: 42', actual: await reportLogins(), typoKeyword: _logins.toString(), ), readableErrors: { typoMessage: typoMessage, 'null': 'Test failed! Did you forget to implement or return from reportLogins?', 'Total number of logins: Instance of \'Future<int>\'': '$testFailedMessage reportLogins. Did you use the await keyword?', 'Total number of logins: Instance of \'_Future<int>\'': '$testFailedMessage reportLogins. Did you use the await keyword?', 'Total number of logins: ': '$testFailedMessage reportLogins. Did you return the number of logins?', 'Total number of logins:': '$testFailedMessage reportLogins. Did you return the number of logins?', 'Total number of logins: 57': '$testFailedMessage reportLogins. Did you invoke fetchLoginAmount to fetch the number of user logins?', })) ..removeWhere((m) => m.contains(passed)) ..toList(); if (messages.isEmpty) { print('Success. All tests passed!'); } else { messages.forEach(print); } } on UnimplementedError { print( 'Test failed! Did you forget to implement or return from reportUserRole?'); } catch (e) { print('Tried to run solution, but received an exception: $e'); } } const _role = 'administrator'; const _logins = 42; const _halfSecond = Duration(milliseconds: 500); // Test helpers. String _makeReadable({ required String testResult, required Map<String, String> readableErrors, required String testLabel, }) { if (readableErrors.containsKey(testResult)) { var readable = readableErrors[testResult]; return '$testLabel $readable'; } else { return '$testLabel $testResult'; } } // Assertions used in tests. Future<String> _asyncEquals({ required String expected, required dynamic actual, required String typoKeyword, }) async { var strActual = actual is String ? actual : actual.toString(); try { if (expected == actual) { return 'PASSED'; } else if (strActual.contains(typoKeyword)) { return 'Test failed! Check for typos in your return value'; } else { return strActual; } } catch (e) { return e.toString(); } } </code></pre><details><summary title="Expand for a hint on the async-await exercise.">Hint</summary><p>Did you remember to add the <code>async</code> keyword to the <code>reportUserRole</code> function?</p><p>Did you remember to use the <code>await</code> keyword before invoking <code>fetchRole()</code>?</p><p>Remember: <code>reportUserRole</code> needs to return a <code>Future</code>.</p></details><details><summary title="Expand for the solution of the async-await exercise.">Solution</summary><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">String</span><span style="color:#222222">> </span><span style="color:#6200EE">reportUserRole</span><span style="color:#222222">() </span><span style="color:#D43324">async</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#D43324"> final</span><span style="color:#222222"> username = </span><span style="color:#D43324">await</span><span style="color:#6200EE"> fetchRole</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#11796D"> 'User role: </span><span style="color:#11796D">$</span><span style="color:#222222">username</span><span style="color:#11796D">'</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#222222">}</span></span> <span class="line"></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">String</span><span style="color:#222222">> </span><span style="color:#6200EE">reportLogins</span><span style="color:#222222">() </span><span style="color:#D43324">async</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#D43324"> final</span><span style="color:#222222"> logins = </span><span style="color:#D43324">await</span><span style="color:#6200EE"> fetchLoginAmount</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#11796D"> 'Total number of logins: </span><span style="color:#11796D">$</span><span style="color:#222222">logins</span><span style="color:#11796D">'</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></details><div class="header-wrapper"><h2 id="handling-errors">Handling errors</h2><a class="heading-link" href="#handling-errors" aria-label="Link to 'Handling errors' section">#</a></div><p>To handle errors in an <code>async</code> function, use try-catch:</p> <?code-excerpt "async_await/bin/try_catch.dart (try-catch)" remove="print(order)"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">try</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#6200EE"> print</span><span style="color:#222222">(</span><span style="color:#11796D">'Awaiting user order...'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> order = </span><span style="color:#D43324">await</span><span style="color:#6200EE"> fetchUserOrder</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#222222">} </span><span style="color:#D43324">catch</span><span style="color:#222222"> (err) {</span></span> <span class="line"><span style="color:#6200EE"> print</span><span style="color:#222222">(</span><span style="color:#11796D">'Caught error: </span><span style="color:#11796D">$</span><span style="color:#222222">err</span><span style="color:#11796D">'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>Within an <code>async</code> function, you can write <a href="/language/error-handling#catch">try-catch clauses</a> the same way you would in synchronous code.</p><div class="header-wrapper"><h3 id="example-async-and-await-with-try-catch">Example: async and await with try-catch</h3><a class="heading-link" href="#example-async-and-await-with-try-catch" aria-label="Link to 'Example: async and await with try-catch' section">#</a></div><p>Run the following example to see how to handle an error from an asynchronous function. What do you think the output will be?</p> <?code-excerpt "async_await/bin/try_catch.dart"?> <pre><code data-dartpad="true" data-embed="true" data-theme="light" title="Runnable Dart sample" data-run="false">Future<void> printOrderMessage() async { try { print('Awaiting user order...'); var order = await fetchUserOrder(); print(order); } catch (err) { print('Caught error: $err'); } } Future<String> fetchUserOrder() { // Imagine that this function is more complex. var str = Future.delayed( const Duration(seconds: 4), () => throw 'Cannot locate user order', ); return str; } void main() async { await printOrderMessage(); } </code></pre><div class="header-wrapper"><h3 id="exercise-practice-handling-errors">Exercise: Practice handling errors</h3><a class="heading-link" href="#exercise-practice-handling-errors" aria-label="Link to 'Exercise: Practice handling errors' section">#</a></div><p>The following exercise provides practice handling errors with asynchronous code, using the approach described in the previous section. To simulate asynchronous operations, your code will call the following function, which is provided for you:</p><div class="table-wrapper"><table class="table table-striped"><thead><tr><th>Function</th><th>Type signature</th><th>Description</th></tr></thead><tbody><tr><td>fetchNewUsername()</td><td><code>Future<String> fetchNewUsername()</code></td><td>Returns the new username that you can use to replace an old one.</td></tr></tbody></table></div><p>Use <code>async</code> and <code>await</code> to implement an asynchronous <code>changeUsername()</code> function that does the following:</p><ul><li>Calls the provided asynchronous function <code>fetchNewUsername()</code> and returns its result.<ul><li>Example return value from <code>changeUsername()</code>: <code>"jane_smith_92"</code></li></ul></li><li>Catches any error that occurs and returns the string value of the error.<ul><li>You can use the <a href="https://api.dart.dev/dart-core/ArgumentError/toString.html">toString()</a> method to stringify both <a href="https://api.dart.dev/dart-core/Exception-class.html">Exceptions</a> and <a href="https://api.dart.dev/dart-core/Error-class.html">Errors.</a></li></ul></li></ul><pre><code data-dartpad="true" data-embed="true" data-theme="dark" title="Runnable Dart sample" data-run="false">// TODO: Implement changeUsername here. changeUsername() {} // The following function is provided to you to simulate // an asynchronous operation that could take a while and // potentially throw an exception. Future<String> fetchNewUsername() => Future.delayed(const Duration(milliseconds: 500), () => throw UserError()); class UserError implements Exception { @override String toString() => 'New username is invalid'; } // The following code is used to test and provide feedback on your solution. // There is no need to read or modify it. void main() async { final List<String> messages = []; const typoMessage = 'Test failed! Check for typos in your return value'; print('Testing...'); try { messages ..add(_makeReadable( testLabel: '', testResult: await _asyncDidCatchException(changeUsername), readableErrors: { typoMessage: typoMessage, _noCatch: 'Did you remember to call fetchNewUsername within a try/catch block?', })) ..add(_makeReadable( testLabel: '', testResult: await _asyncErrorEquals(changeUsername), readableErrors: { typoMessage: typoMessage, _noCatch: 'Did you remember to call fetchNewUsername within a try/catch block?', })) ..removeWhere((m) => m.contains(_passed)) ..toList(); if (messages.isEmpty) { print('Success. All tests passed!'); } else { messages.forEach(print); } } catch (e) { print('Tried to run solution, but received an exception: $e'); } } // Test helpers. String _makeReadable({ required String testResult, required Map<String, String> readableErrors, required String testLabel, }) { if (readableErrors.containsKey(testResult)) { final readable = readableErrors[testResult]; return '$testLabel $readable'; } else { return '$testLabel $testResult'; } } Future<String> _asyncErrorEquals(Function fn) async { final result = await fn(); if (result == UserError().toString()) { return _passed; } else { return 'Test failed! Did you stringify and return the caught error?'; } } Future<String> _asyncDidCatchException(Function fn) async { var caught = true; try { await fn(); } on UserError catch (_) { caught = false; } if (caught == false) { return _noCatch; } else { return _passed; } } const _passed = 'PASSED'; const _noCatch = 'NO_CATCH'; </code></pre><details><summary title="Expand for a hint on the error-handling exercise.">Hint</summary><p>Implement <code>changeUsername</code> to return the string from <code>fetchNewUsername</code> or, if that fails, the string value of any error that occurs.</p><p>Remember: You can use a <a href="/language/error-handling#catch">try-catch statement</a> to catch and handle errors.</p></details><details><summary title="Expand for the solution of the error-handling exercise.">Solution</summary><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">String</span><span style="color:#222222">> </span><span style="color:#6200EE">changeUsername</span><span style="color:#222222">() </span><span style="color:#D43324">async</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#D43324"> try</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#D43324"> await</span><span style="color:#6200EE"> fetchNewUsername</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#222222"> } </span><span style="color:#D43324">catch</span><span style="color:#222222"> (err) {</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#222222"> err.</span><span style="color:#6200EE">toString</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></details><div class="header-wrapper"><h2 id="exercise-putting-it-all-together">Exercise: Putting it all together</h2><a class="heading-link" href="#exercise-putting-it-all-together" aria-label="Link to 'Exercise: Putting it all together' section">#</a></div><p>It's time to practice what you've learned in one final exercise. To simulate asynchronous operations, this exercise provides the asynchronous functions <code>fetchUsername()</code> and <code>logoutUser()</code>:</p><div class="table-wrapper"><table class="table table-striped"><thead><tr><th>Function</th><th>Type signature</th><th>Description</th></tr></thead><tbody><tr><td>fetchUsername()</td><td><code>Future<String> fetchUsername()</code></td><td>Returns the name associated with the current user.</td></tr><tr><td>logoutUser()</td><td><code>Future<String> logoutUser()</code></td><td>Performs logout of current user and returns the username that was logged out.</td></tr></tbody></table></div><p>Write the following:</p><div class="header-wrapper"><h4 id="part-1-addhello">Part 1: <code>addHello()</code></h4><a class="heading-link" href="#part-1-addhello" aria-label="Link to 'Part 1: addHello()' section">#</a></div><ul><li>Write a function <code>addHello()</code> that takes a single <code>String</code> argument.</li><li><code>addHello()</code> returns its <code>String</code> argument preceded by <code>'Hello '</code>.<br>Example: <code>addHello('Jon')</code> returns <code>'Hello Jon'</code>.</li></ul><div class="header-wrapper"><h4 id="part-2-greetuser">Part 2: <code>greetUser()</code></h4><a class="heading-link" href="#part-2-greetuser" aria-label="Link to 'Part 2: greetUser()' section">#</a></div><ul><li>Write a function <code>greetUser()</code> that takes no arguments.</li><li>To get the username, <code>greetUser()</code> calls the provided asynchronous function <code>fetchUsername()</code>.</li><li><code>greetUser()</code> creates a greeting for the user by calling <code>addHello()</code>, passing it the username, and returning the result.<br>Example: If <code>fetchUsername()</code> returns <code>'Jenny'</code>, then <code>greetUser()</code> returns <code>'Hello Jenny'</code>.</li></ul><div class="header-wrapper"><h4 id="part-3-saygoodbye">Part 3: <code>sayGoodbye()</code></h4><a class="heading-link" href="#part-3-saygoodbye" aria-label="Link to 'Part 3: sayGoodbye()' section">#</a></div><ul><li>Write a function <code>sayGoodbye()</code> that does the following:<ul><li>Takes no arguments.</li><li>Catches any errors.</li><li>Calls the provided asynchronous function <code>logoutUser()</code>.</li></ul></li><li>If <code>logoutUser()</code> fails, <code>sayGoodbye()</code> returns any string you like.</li><li>If <code>logoutUser()</code> succeeds, <code>sayGoodbye()</code> returns the string <code>'<result> Thanks, see you next time'</code>, where <code><result></code> is the string value returned by calling <code>logoutUser()</code>.</li></ul><pre><code data-dartpad="true" data-embed="true" data-theme="dark" title="Runnable Dart sample" data-run="false">// Part 1 addHello(String user) {} // Part 2 // Call the provided async function fetchUsername() // to return the username. greetUser() {} // Part 3 // Call the provided async function logoutUser() // to log out the user. sayGoodbye() {} // The following functions are provided to you to use in your solutions. Future<String> fetchUsername() => Future.delayed(_halfSecond, () => 'Jean'); Future<String> logoutUser() => Future.delayed(_halfSecond, _failOnce); // The following code is used to test and provide feedback on your solution. // There is no need to read or modify it. void main() async { const didNotImplement = 'Test failed! Did you forget to implement or return from'; final List<String> messages = []; print('Testing...'); try { messages ..add(_makeReadable( testLabel: 'Part 1', testResult: await _asyncEquals( expected: 'Hello Jerry', actual: addHello('Jerry'), typoKeyword: 'Jerry'), readableErrors: { _typoMessage: _typoMessage, 'null': '$didNotImplement addHello?', 'Hello Instance of \'Future<String>\'': 'Looks like you forgot to use the \'await\' keyword!', 'Hello Instance of \'_Future<String>\'': 'Looks like you forgot to use the \'await\' keyword!', })) ..add(_makeReadable( testLabel: 'Part 2', testResult: await _asyncEquals( expected: 'Hello Jean', actual: await greetUser(), typoKeyword: 'Jean'), readableErrors: { _typoMessage: _typoMessage, 'null': '$didNotImplement greetUser?', 'HelloJean': 'Looks like you forgot the space between \'Hello\' and \'Jean\'', 'Hello Instance of \'Future<String>\'': 'Looks like you forgot to use the \'await\' keyword!', 'Hello Instance of \'_Future<String>\'': 'Looks like you forgot to use the \'await\' keyword!', '{Closure: (String) => dynamic from Function \'addHello\': static.(await fetchUsername())}': 'Did you place the \'\$\' character correctly?', '{Closure \'addHello\'(await fetchUsername())}': 'Did you place the \'\$\' character correctly?', })) ..add(_makeReadable( testLabel: 'Part 3', testResult: await _asyncDidCatchException(sayGoodbye), readableErrors: { _typoMessage: '$_typoMessage. Did you add the text \'Thanks, see you next time\'?', 'null': '$didNotImplement sayGoodbye?', _noCatch: 'Did you remember to call logoutUser within a try/catch block?', 'Instance of \'Future<String>\' Thanks, see you next time': 'Did you remember to use the \'await\' keyword in the sayGoodbye function?', 'Instance of \'_Future<String>\' Thanks, see you next time': 'Did you remember to use the \'await\' keyword in the sayGoodbye function?', })) ..add(_makeReadable( testLabel: 'Part 3', testResult: await _asyncEquals( expected: 'Success! Thanks, see you next time', actual: await sayGoodbye(), typoKeyword: 'Success'), readableErrors: { _typoMessage: '$_typoMessage. Did you add the text \'Thanks, see you next time\'?', 'null': '$didNotImplement sayGoodbye?', _noCatch: 'Did you remember to call logoutUser within a try/catch block?', 'Instance of \'Future<String>\' Thanks, see you next time': 'Did you remember to use the \'await\' keyword in the sayGoodbye function?', 'Instance of \'_Future<String>\' Thanks, see you next time': 'Did you remember to use the \'await\' keyword in the sayGoodbye function?', 'Instance of \'_Exception\'': 'CAUGHT Did you remember to return a string?', })) ..removeWhere((m) => m.contains(_passed)) ..toList(); if (messages.isEmpty) { print('Success. All tests passed!'); } else { messages.forEach(print); } } catch (e) { print('Tried to run solution, but received an exception: $e'); } } // Test helpers. String _makeReadable({ required String testResult, required Map<String, String> readableErrors, required String testLabel, }) { String? readable; if (readableErrors.containsKey(testResult)) { readable = readableErrors[testResult]; return '$testLabel $readable'; } else if ((testResult != _passed) && (testResult.length < 18)) { readable = _typoMessage; return '$testLabel $readable'; } else { return '$testLabel $testResult'; } } Future<String> _asyncEquals({ required String expected, required dynamic actual, required String typoKeyword, }) async { final strActual = actual is String ? actual : actual.toString(); try { if (expected == actual) { return _passed; } else if (strActual.contains(typoKeyword)) { return _typoMessage; } else { return strActual; } } catch (e) { return e.toString(); } } Future<String> _asyncDidCatchException(Function fn) async { var caught = true; try { await fn(); } on Exception catch (_) { caught = false; } if (caught == true) { return _passed; } else { return _noCatch; } } const _typoMessage = 'Test failed! Check for typos in your return value'; const _passed = 'PASSED'; const _noCatch = 'NO_CATCH'; const _halfSecond = Duration(milliseconds: 500); String _failOnce() { if (_logoutSucceeds) { return 'Success!'; } else { _logoutSucceeds = true; throw Exception('Logout failed'); } } bool _logoutSucceeds = false; </code></pre><details><summary title="Expand for a hint on the 'Putting it all together' exercise.">Hint</summary><p>The <code>greetUser</code> and <code>sayGoodbye</code> functions should be asynchronous, while <code>addHello</code> should be a normal, synchronous function.</p><p>Remember: You can use a <a href="/language/error-handling#catch">try-catch statement</a> to catch and handle errors.</p></details><details><summary title="Expand for the solution of the 'Putting it all together' exercise.">Solution</summary><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">String</span><span style="color:#6200EE"> addHello</span><span style="color:#222222">(</span><span style="color:#0468D7">String</span><span style="color:#222222"> user) => </span><span style="color:#11796D">'Hello </span><span style="color:#11796D">$</span><span style="color:#222222">user</span><span style="color:#11796D">'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">String</span><span style="color:#222222">> </span><span style="color:#6200EE">greetUser</span><span style="color:#222222">() </span><span style="color:#D43324">async</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#D43324"> final</span><span style="color:#222222"> username = </span><span style="color:#D43324">await</span><span style="color:#6200EE"> fetchUsername</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#6200EE"> addHello</span><span style="color:#222222">(username);</span></span> <span class="line"><span style="color:#222222">}</span></span> <span class="line"></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">String</span><span style="color:#222222">> </span><span style="color:#6200EE">sayGoodbye</span><span style="color:#222222">() </span><span style="color:#D43324">async</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#D43324"> try</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#D43324"> final</span><span style="color:#222222"> result = </span><span style="color:#D43324">await</span><span style="color:#6200EE"> logoutUser</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#11796D"> '</span><span style="color:#11796D">$</span><span style="color:#222222">result</span><span style="color:#11796D"> Thanks, see you next time'</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#222222"> } </span><span style="color:#D43324">catch</span><span style="color:#222222"> (e) {</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#11796D"> 'Failed to logout user: </span><span style="color:#11796D">$</span><span style="color:#222222">e</span><span style="color:#11796D">'</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></details><div class="header-wrapper"><h2 id="which-lints-work-for-futures">Which lints work for futures?</h2><a class="heading-link" href="#which-lints-work-for-futures" aria-label="Link to 'Which lints work for futures?' section">#</a></div><p>To catch common mistakes that arise while working with async and futures, <a href="/tools/analysis#individual-rules">enable</a> the following lints:</p><ul><li><a href="/tools/linter-rules/discarded_futures"><code>discarded_futures</code></a></li><li><a href="/tools/linter-rules/unawaited_futures"><code>unawaited_futures</code></a></li></ul><div class="header-wrapper"><h2 id="whats-next">What's next?</h2><a class="heading-link" href="#whats-next" aria-label="Link to 'What's next?' section">#</a></div><p>Congratulations, you've finished the tutorial! If you'd like to learn more, here are some suggestions for where to go next:</p><ul><li>Play with <a href="https://dartpad.dev">DartPad</a>.</li><li>Try another <a href="/tutorials">tutorial</a>.</li><li>Learn more about futures and asynchronous code in Dart:<ul><li><a href="/libraries/async/using-streams">Streams tutorial</a>: Learn how to work with a sequence of asynchronous events.</li><li><a href="/language/concurrency">Concurrency in Dart</a>: Understand and learn how to implement concurrency in Dart.</li><li><a href="/language/async">Asynchrony support</a>: Dive in to Dart's language and library support for asynchronous coding.</li><li><a href="https://www.youtube.com/playlist?list=PLjxrf2q8roU0Net_g1NT5_vOO3s_FR02J">Dart videos from Google</a>: Watch one or more of the videos about asynchronous coding.</li></ul></li><li>Get the <a href="/get-dart">Dart SDK</a>!</li></ul><p id="page-github-links"><span>Unless stated otherwise, the documentation on this site reflects Dart 3.7.2. Page last updated on 2025-02-12.</span> <a href="https://github.com/dart-lang/site-www/tree/main/src/content/libraries/async/async-await.md" target="_blank" rel="noopener">View source</a> <span>or </span><a href="https://github.com/dart-lang/site-www/issues/new?template=1_page_issue.yml&page-url=https://dart.dev/libraries/async/async-await/&page-source=https://github.com/dart-lang/site-www/tree/main/src/content/libraries/async/async-await.md" title="Report an issue with this page" target="_blank" rel="noopener">report an issue</a>.</p></div></article></main></div><footer id="page-footer"><div class="footer-section footer-main"><a href="/" class="brand" title="Dart"><img src="/assets/img/logo/logo-white-text.svg" alt="Dart" width="164"></a><div class="footer-social-links"><a href="https://medium.com/dartlang" target="_blank" rel="noopener" title="Dart's Medium publication"><svg><use href="/assets/img/social/medium.svg#medium"></use></svg> </a><a href="https://github.com/dart-lang" target="_blank" rel="noopener" title="Dart's GitHub organization"><svg><use href="/assets/img/social/github.svg#github"></use></svg> </a><a href="https://bsky.app/profile/dart.dev" target="_blank" rel="noopener" title="Dart's Bluesky profile"><svg><use href="/assets/img/social/bluesky.svg#bluesky"></use></svg> </a><a href="https://twitter.com/dart_lang" target="_blank" rel="noopener" title="Dart's X (Twitter) profile"><svg><use href="/assets/img/social/x.svg#x"></use></svg></a></div></div><div class="footer-section footer-tray"><div class="footer-licenses">Except as otherwise noted, this site is licensed under a <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>, and code samples are licensed under the <a href="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</a>.</div><div class="footer-utility-links"><ul><li><a href="/terms" title="Terms of use">Terms</a></li><li><a href="https://policies.google.com/privacy" target="_blank" rel="noopener" title="Privacy policy">Privacy</a></li><li><a href="/security" title="Security philosophy and practices">Security</a></li></ul></div></div></footer></div></body></html>