CINXE.COM
Asynchronous programming: Streams | 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 how to consume single-subscriber and broadcast streams."><title>Asynchronous programming: Streams | 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: Streams"><meta name="twitter:description" content="Learn how to consume single-subscriber and broadcast streams."><meta property="og:title" content="Asynchronous programming: Streams"><meta property="og:description" content="Learn how to consume single-subscriber and broadcast streams."><meta property="og:url" content="/libraries/async/using-streams/"><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,0" rel="stylesheet"><link rel="stylesheet" href="/assets/css/main.css"><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js" integrity="sha512-3gJwYpMe3QewGELv8k/BX9vcqhryRdzRMxVfq6ngyWXwo03GFEzjsUm8Q7RZcHPHksttq7/GFoxjCVUjkjvPdw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/js/bootstrap.min.js" integrity="sha384-+sLIOodYLS7CIrQpBjl+C7nPvqq+FbNUBDunl/OZv93DB7Ln/533i8e/mZXLi/P+" crossorigin="anonymous" referrerpolicy="no-referrer"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/js-cookie/3.0.5/js.cookie.min.js" integrity="sha512-nlp9/l96/EpjYBx7EP7pGASVXNe80hGhYAUrjeXnu/fyF5Py0/RXav4BBNs7n5Hx1WFhOEOWSAVjGeC3oKxDVQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script><script src="/assets/js/os-tabs.js"></script><script src="/assets/js/utilities.js"></script><script src="/assets/js/main.js"></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 show_banner"><a id="skip" href="#site-content-title">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. <a href="https://policies.google.com/technologies/cookies" target="_blank" rel="noopener">Learn more</a>.</p><button id="cookie-consent" class="btn btn-primary">OK, got it</button></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><header id="page-header" class="site-header"><nav id="mainnav" class="site-header"><div id="menu-toggle"><i class="material-symbols">menu</i></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="/guides" 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 class="banner"><p class="banner__text">Announcing Dart 3.5 and an updated Dart roadmap! <a href="https://medium.com/dartlang/dart-3-5-6ca36259fa2f" target="_blank">Learn more</a></p></div><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><div class="site-sidebar"><ul class="navbar-nav"><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="/guides" class="nav-link">Docs</a></li><li aria-hidden="true"><div class="sidebar-primary-divider"></div></li></ul><ul class="nav flex-column"><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#sidenav-1" role="button" aria-expanded="false" aria-controls="sidenav-1">Language</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-1"><li class="nav-item"><a class="nav-link" href="/language">Introduction</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-1-2" href="#sidenav-1-2" role="button" aria-expanded="false" aria-controls="sidenav-1-2">Syntax basics</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-1-2"><li class="nav-item"><a class="nav-link" href="/language/variables">Variables</a></li><li class="nav-item"><a class="nav-link" href="/language/operators">Operators</a></li><li class="nav-item"><a class="nav-link" href="/language/comments">Comments</a></li><li class="nav-item"><a class="nav-link" href="/language/metadata">Metadata</a></li><li class="nav-item"><a class="nav-link" href="/language/libraries">Libraries & imports</a></li><li class="nav-item"><a class="nav-link" href="/language/keywords">Keywords</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-1-3" href="#sidenav-1-3" role="button" aria-expanded="false" aria-controls="sidenav-1-3">Types</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-1-3"><li class="nav-item"><a class="nav-link" href="/language/built-in-types">Built-in types</a></li><li class="nav-item"><a class="nav-link" href="/language/records">Records</a></li><li class="nav-item"><a class="nav-link" href="/language/collections">Collections</a></li><li class="nav-item"><a class="nav-link" href="/language/generics">Generics</a></li><li class="nav-item"><a class="nav-link" href="/language/typedefs">Typedefs</a></li><li class="nav-item"><a class="nav-link" href="/language/type-system">Type system</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-1-4" href="#sidenav-1-4" role="button" aria-expanded="false" aria-controls="sidenav-1-4">Patterns</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-1-4"><li class="nav-item"><a class="nav-link" href="/language/patterns">Overview & usage</a></li><li class="nav-item"><a class="nav-link" href="/language/pattern-types">Pattern types</a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/dart-patterns-records" target="_blank" rel="noopener">Applied tutorial</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/language/functions">Functions</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-1-6" href="#sidenav-1-6" role="button" aria-expanded="false" aria-controls="sidenav-1-6">Control flow</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-1-6"><li class="nav-item"><a class="nav-link" href="/language/loops">Loops</a></li><li class="nav-item"><a class="nav-link" href="/language/branches">Branches</a></li><li class="nav-item"><a class="nav-link" href="/language/error-handling">Error handling</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-1-7" href="#sidenav-1-7" role="button" aria-expanded="false" aria-controls="sidenav-1-7">Classes & objects</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-1-7"><li class="nav-item"><a class="nav-link" href="/language/classes">Classes</a></li><li class="nav-item"><a class="nav-link" href="/language/constructors">Constructors</a></li><li class="nav-item"><a class="nav-link" href="/language/methods">Methods</a></li><li class="nav-item"><a class="nav-link" href="/language/extend">Extend a class</a></li><li class="nav-item"><a class="nav-link" href="/language/mixins">Mixins</a></li><li class="nav-item"><a class="nav-link" href="/language/enums">Enums</a></li><li class="nav-item"><a class="nav-link" href="/language/extension-methods">Extension methods</a></li><li class="nav-item"><a class="nav-link" href="/language/extension-types">Extension types</a></li><li class="nav-item"><a class="nav-link" href="/language/callable-objects">Callable objects</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-1-8" href="#sidenav-1-8" role="button" aria-expanded="false" aria-controls="sidenav-1-8">Class modifiers</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-1-8"><li class="nav-item"><a class="nav-link" href="/language/class-modifiers">Overview & usage</a></li><li class="nav-item"><a class="nav-link" href="/language/class-modifiers-for-apis">Class modifiers for API maintainers</a></li><li class="nav-item"><a class="nav-link" href="/language/modifier-reference">Reference</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-1-9" href="#sidenav-1-9" role="button" aria-expanded="false" aria-controls="sidenav-1-9">Concurrency</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-1-9"><li class="nav-item"><a class="nav-link" href="/language/concurrency">Overview</a></li><li class="nav-item"><a class="nav-link" href="/language/async">Asynchronous support</a></li><li class="nav-item"><a class="nav-link" href="/language/isolates">Isolates</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-1-10" href="#sidenav-1-10" role="button" aria-expanded="false" aria-controls="sidenav-1-10">Null safety</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-1-10"><li class="nav-item"><a class="nav-link" href="/null-safety">Sound null safety</a></li><li class="nav-item"><a class="nav-link" href="/null-safety/migration-guide">Migrating to null safety</a></li><li class="nav-item"><a class="nav-link" href="/null-safety/understanding-null-safety">Understanding null safety</a></li><li class="nav-item"><a class="nav-link" href="/null-safety/unsound-null-safety">Unsound null safety</a></li><li class="nav-item"><a class="nav-link" href="/null-safety/faq">FAQ</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link active collapsible" data-toggle="collapse" href="#sidenav-2" role="button" aria-expanded="true" aria-controls="sidenav-2">Core libraries</a><ul class="nav flex-column flex-nowrap collapse show" id="sidenav-2"><li class="nav-item"><a class="nav-link" href="/libraries">Overview</a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-core">dart:core</a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-async">dart:async</a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-math">dart:math</a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-convert">dart:convert</a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-io">dart:io</a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-html">dart:html</a></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link" href="/libraries/collections/iterables">Iterable collections</a></li><li class="nav-item"><a class="nav-link active collapsible" data-toggle="collapse" data-target="#sidenav-2-10" href="#sidenav-2-10" role="button" aria-expanded="true" aria-controls="sidenav-2-10">Asynchronous programming</a><ul class="nav flex-column flex-nowrap collapse show" id="sidenav-2-10"><li class="nav-item"><a class="nav-link" href="/libraries/async/async-await">Tutorial</a></li><li class="nav-item"><a class="nav-link" href="/libraries/async/futures-error-handling">Futures and error handling</a></li><li class="nav-item"><a class="nav-link active" href="/libraries/async/using-streams">Using streams</a></li><li class="nav-item"><a class="nav-link" href="/libraries/async/creating-streams">Creating streams</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#sidenav-3" role="button" aria-expanded="false" aria-controls="sidenav-3">Effective Dart</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-3"><li class="nav-item"><a class="nav-link" href="/effective-dart">Overview</a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/style">Style</a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/documentation">Documentation</a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/usage">Usage</a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/design">Design</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#sidenav-4" role="button" aria-expanded="false" aria-controls="sidenav-4">Packages</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-4"><li class="nav-item"><a class="nav-link" href="/tools/pub/packages">How to use packages</a></li><li class="nav-item"><a class="nav-link" href="/resources/useful-packages">Commonly used packages</a></li><li class="nav-item"><a class="nav-link" href="/guides/libraries/create-packages">Creating packages</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/publishing">Publishing packages</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/writing-package-pages">Writing package pages</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-4-6" href="#sidenav-4-6" role="button" aria-expanded="false" aria-controls="sidenav-4-6">Package reference</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-4-6"><li class="nav-item"><a class="nav-link" href="/tools/pub/dependencies">Dependencies</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/glossary">Glossary</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/package-layout">Package layout conventions</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/environment-variables">Pub environment variables</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/pubspec">Pubspec file</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/troubleshoot">Troubleshooting pub</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/verified-publishers">Verified publishers</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/security-advisories">Security advisories</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/versioning">Versioning</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/custom-package-repositories">Custom package repositories</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/guides/libraries/private-files">What not to commit</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#sidenav-5" role="button" aria-expanded="false" aria-controls="sidenav-5">Development</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-5"><li class="nav-item"><a class="nav-link" href="/guides/json">JSON</a></li><li class="nav-item"><a class="nav-link" href="/guides/language/numbers">Number representation</a></li><li class="nav-item"><a class="nav-link" href="/resources/google-apis">Google APIs</a></li><li class="nav-item"><a class="nav-link" href="/multiplatform-apps">Multi-platform apps</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-5" href="#sidenav-5-5" role="button" aria-expanded="false" aria-controls="sidenav-5-5">Command-line & server apps</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-5-5"><li class="nav-item"><a class="nav-link" href="/server">Overview</a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/get-started">Get started</a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/cmdline">Write command-line apps</a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/fetch-data">Fetch data from the internet</a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/httpserver">Write HTTP servers</a></li><li class="nav-item"><a class="nav-link" href="/server/libraries">Libraries & packages</a></li><li class="nav-item"><a class="nav-link" href="/server/google-cloud">Google Cloud</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-6" href="#sidenav-5-6" role="button" aria-expanded="false" aria-controls="sidenav-5-6">Web apps</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-5-6"><li class="nav-item"><a class="nav-link" href="/web">Overview</a></li><li class="nav-item"><a class="nav-link" href="/web/get-started">Get started</a></li><li class="nav-item"><a class="nav-link" href="/web/deployment">Deployment</a></li><li class="nav-item"><a class="nav-link" href="/web/libraries">Libraries & packages</a></li><li class="nav-item"><a class="nav-link" href="/web/wasm">Wasm compilation</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/guides/environment-declarations">Environment declarations</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#sidenav-6" role="button" aria-expanded="false" aria-controls="sidenav-6">Interoperability</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-6"><li class="nav-item"><a class="nav-link" href="/interop/c-interop">C interop</a></li><li class="nav-item"><a class="nav-link" href="/interop/objective-c-interop">Objective-C & Swift interop</a></li><li class="nav-item"><a class="nav-link" href="/interop/java-interop">Java & Kotlin interop</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-6-4" href="#sidenav-6-4" role="button" aria-expanded="false" aria-controls="sidenav-6-4">JavaScript interop</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-6-4"><li class="nav-item"><a class="nav-link" href="/interop/js-interop">Overview</a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop/usage">Usage</a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop/js-types">JS types</a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop/tutorials">Tutorials</a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop/past-js-interop">Past JS interop</a></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link" href="/interop/js-interop/package-web">Web interop</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#sidenav-7" role="button" aria-expanded="false" aria-controls="sidenav-7">Tools & techniques</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-7"><li class="nav-item"><a class="nav-link" href="/tools">Overview</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-7-2" href="#sidenav-7-2" role="button" aria-expanded="false" aria-controls="sidenav-7-2">Editors & debuggers</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-7-2"><li class="nav-item"><a class="nav-link" href="/tools/jetbrains-plugin">IntelliJ & Android Studio</a></li><li class="nav-item"><a class="nav-link" href="/tools/vs-code">VS Code</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-devtools">Dart DevTools</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-7-2-4" href="#sidenav-7-2-4" role="button" aria-expanded="false" aria-controls="sidenav-7-2-4">DartPad</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-7-2-4"><li class="nav-item"><a class="nav-link" href="/tools/dartpad">Overview</a></li><li class="nav-item"><a class="nav-link" href="/tools/dartpad/troubleshoot">Troubleshooting DartPad</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-7-3" href="#sidenav-7-3" role="button" aria-expanded="false" aria-controls="sidenav-7-3">Command-line tools</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-7-3"><li class="nav-item"><a class="nav-link collapsible" data-toggle="collapse" data-target="#sidenav-7-3-1" href="#sidenav-7-3-1" role="button" aria-expanded="true" aria-controls="sidenav-7-3-1">Dart SDK</a><ul class="nav flex-column flex-nowrap collapse show" id="sidenav-7-3-1"><li class="nav-item"><a class="nav-link" href="/tools/sdk">Overview</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-tool">dart</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-analyze">dart analyze</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-compile">dart compile</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-create">dart create</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-doc">dart doc</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-fix">dart fix</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-format">dart format</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-info">dart info</a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/cmd">dart pub</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-run">dart run</a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-test">dart test</a></li><li class="nav-item"><a class="nav-link" href="/tools/dartaotruntime">dartaotruntime</a></li><li class="nav-item"><a class="nav-link" href="/tools/experiment-flags">Experiment flags</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible" data-toggle="collapse" data-target="#sidenav-7-3-2" href="#sidenav-7-3-2" role="button" aria-expanded="true" aria-controls="sidenav-7-3-2">Other command-line tools</a><ul class="nav flex-column flex-nowrap collapse show" id="sidenav-7-3-2"><li class="nav-item"><a class="nav-link" href="/tools/build_runner">build_runner</a></li><li class="nav-item"><a class="nav-link" href="/tools/webdev">webdev</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-7-4" href="#sidenav-7-4" role="button" aria-expanded="false" aria-controls="sidenav-7-4">Static analysis</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-7-4"><li class="nav-item"><a class="nav-link" href="/tools/analysis">Customizing static analysis</a></li><li class="nav-item"><a class="nav-link" href="/guides/language/sound-problems">Fixing common type problems</a></li><li class="nav-item"><a class="nav-link" href="/tools/non-promotion-reasons">Fixing type promotion failures</a></li><li class="nav-item"><a class="nav-link" href="/tools/linter-rules">Linter rules</a></li><li class="nav-item"><a class="nav-link" href="/tools/diagnostic-messages">Diagnostic messages</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-7-5" href="#sidenav-7-5" role="button" aria-expanded="false" aria-controls="sidenav-7-5">Testing & optimization</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-7-5"><li class="nav-item"><a class="nav-link" href="/guides/testing">Testing</a></li><li class="nav-item"><a class="nav-link" href="/web/debugging">Debugging web apps</a></li></ul></li></ul></li><li aria-hidden="true"><div class="sidebar-primary-divider"></div></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#sidenav-9" role="button" aria-expanded="false" aria-controls="sidenav-9">Resources</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-9"><li class="nav-item"><a class="nav-link" href="/resources/dart-cheatsheet">Language cheatsheet</a></li><li class="nav-item"><a class="nav-link" href="/resources/breaking-changes">Breaking changes</a></li><li class="nav-item"><a class="nav-link" href="/guides/language/evolution">Language evolution</a></li><li class="nav-item"><a class="nav-link" href="/guides/language/spec">Language specification</a></li><li class="nav-item"><a class="nav-link" href="/resources/dart-3-migration">Dart 3 migration guide</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-9-6" href="#sidenav-9-6" role="button" aria-expanded="false" aria-controls="sidenav-9-6">Coming from ...</a><ul class="nav flex-column flex-nowrap collapse" id="sidenav-9-6"><li class="nav-item"><a class="nav-link" href="/resources/coming-from/js-to-dart">JavaScript to Dart</a></li><li class="nav-item"><a class="nav-link" href="/resources/coming-from/swift-to-dart">Swift to Dart</a></li></ul></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link" href="/resources/faq">FAQ</a></li><li class="nav-item"><a class="nav-link" href="/resources/glossary">Glossary</a></li><li class="nav-item"><a class="nav-link" href="/resources/books">Books</a></li><li class="nav-item"><a class="nav-link" href="/resources/videos">Videos</a></li><li class="nav-item"><a class="nav-link" href="/tutorials">Tutorials</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible" data-toggle="collapse" href="#sidenav-10" role="button" aria-expanded="true" aria-controls="sidenav-10">Related sites</a><ul class="nav flex-column flex-nowrap collapse show" id="sidenav-10"><li class="nav-item"><a class="nav-link" href="https://api.dart.dev" target="_blank" rel="noopener">API reference</a></li><li class="nav-item"><a class="nav-link" href="https://medium.com/dartlang" target="_blank" rel="noopener">Blog</a></li><li class="nav-item"><a class="nav-link" href="https://dartpad.dev" target="_blank" rel="noopener">DartPad (online editor)</a></li><li class="nav-item"><a class="nav-link" href="https://flutter.dev" target="_blank" rel="noopener">Flutter</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev" target="_blank" rel="noopener">Package site</a></li></ul></li></ul></div></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="#receiving-stream-events">Receiving stream events</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#error-events">Error events</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#working-with-streams">Working with streams</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#two-kinds-of-streams">Two kinds of streams</a><ul class="nav"><li class="toc-entry nav-item"><a class="nav-link" href="#single-subscription-streams">Single subscription streams</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#broadcast-streams">Broadcast streams</a></li></ul></li><li class="toc-entry nav-item"><a class="nav-link" href="#process-stream-methods">Methods that process a stream</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#modify-stream-methods">Methods that modify a stream</a><ul class="nav"><li class="toc-entry nav-item"><a class="nav-link" href="#transform-function">The transform() function</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#reading-decoding-file">Reading and decoding a file</a></li></ul></li><li class="toc-entry nav-item"><a class="nav-link" href="#listen-method">The listen() method</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#other-resources">Other resources</a></li></ul></div><article><div class="content"><div id="site-content-title"><h1>Asynchronous programming: Streams</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="#receiving-stream-events">Receiving stream events</a></li><li class="toc-entry"><a href="#error-events">Error events</a></li><li class="toc-entry"><a href="#working-with-streams">Working with streams</a></li><li class="toc-entry"><a href="#two-kinds-of-streams">Two kinds of streams</a><ul><li class="toc-entry"><a href="#single-subscription-streams">Single subscription streams</a></li><li class="toc-entry"><a href="#broadcast-streams">Broadcast streams</a></li></ul></li><li class="toc-entry"><a href="#process-stream-methods">Methods that process a stream</a></li><li class="toc-entry"><a href="#modify-stream-methods">Methods that modify a stream</a><ul><li class="toc-entry"><a href="#transform-function">The transform() function</a></li><li class="toc-entry"><a href="#reading-decoding-file">Reading and decoding a file</a></li></ul></li><li class="toc-entry"><a href="#listen-method">The listen() method</a></li><li class="toc-entry"><a href="#other-resources">Other resources</a></li></ul><span class="site-toc--inline__toggle toc-toggle-more-items"><i class="material-symbols">more_horiz</i></span></div><aside class="alert alert-secondary"><div class="alert-header"><span>What's the point?</span></div><div class="alert-content"><ul><li>Streams provide an asynchronous sequence of data.</li><li>Data sequences include user-generated events and data read from files.</li><li>You can process a stream using either <strong>await for</strong> or <code>listen()</code> from the Stream API.</li><li>Streams provide a way to respond to errors.</li><li>There are two kinds of streams: single subscription or broadcast.</li></ul></div></aside><p>Asynchronous programming in Dart is characterized by the <a href="https://api.dart.dev/dart-async/Future-class.html">Future</a> and <a href="https://api.dart.dev/dart-async/Stream-class.html">Stream</a> classes.</p><p>A Future represents a computation that doesn't complete immediately. Where a normal function returns the result, an asynchronous function returns a Future, which will eventually contain the result. The future will tell you when the result is ready.</p><p>A stream is a sequence of asynchronous events. It is like an asynchronous Iterable鈥攚here, instead of getting the next event when you ask for it, the stream tells you that there is an event when it is ready.</p><div class="header-wrapper"><h2 id="receiving-stream-events">Receiving stream events</h2><a class="heading-link" href="#receiving-stream-events" aria-label="Link to 'Receiving stream events' section">#</a></div><p>Streams can be created in many ways, which is a topic for another article, but they can all be used in the same way: the <em>asynchronous for loop</em> (commonly just called <strong>await for</strong>) iterates over the events of a stream like the <strong>for loop</strong> iterates over an <a href="https://api.dart.dev/dart-core/Iterable-class.html">Iterable</a>. For example:</p> <?code-excerpt "misc/lib/tutorial/sum_stream.dart (sum-stream)" replace="/async|await for/[!$&!]/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">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">int</span><span style="color:#222222">> </span><span style="color:#6200EE">sumStream</span><span style="color:#222222">(</span><span style="color:#0468D7">Stream</span><span style="color:#222222"><</span><span style="color:#0468D7">int</span><span style="color:#222222">> stream) </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"> sum = </span><span style="color:#11796D">0</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#D43324"> </span><mark class="highlight"><span style="color:#D43324">await</span><span style="color:#D43324"> for</span></mark><span style="color:#222222"> (</span><span style="color:#D43324">final</span><span style="color:#222222"> value </span><span style="color:#D43324">in</span><span style="color:#222222"> stream) {</span></span> <span class="line"><span style="color:#222222"> sum += value;</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#222222"> sum;</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>This code simply receives each event of a stream of integer events, adds them up, and returns (a future of) the sum. When the loop body ends, the function is paused until the next event arrives or the stream is done.</p><p>The function is marked with the <code>async</code> keyword, which is required when using the <strong>await for</strong> loop.</p><p>The following example tests the previous code by generating a simple stream of integers using an <code>async*</code> function:</p><aside class="alert alert-info"><div class="alert-header"><i class="material-symbols" aria-hidden="true">info</i> <span>Note</span></div><div class="alert-content"><p>This page uses embedded DartPads to display runnable examples. If you see empty boxes instead of DartPads, go to the <a href="/tools/dartpad/troubleshoot">DartPad troubleshooting page</a>.</p></div></aside> <?code-excerpt "misc/lib/tutorial/sum_stream.dart"?> <pre><code data-dartpad="true" data-embed="true" data-theme="light" title="Runnable Dart sample" data-run="false">Future<int> sumStream(Stream<int> stream) async { var sum = 0; await for (final value in stream) { sum += value; } return sum; } Stream<int> countStream(int to) async* { for (int i = 1; i <= to; i++) { yield i; } } void main() async { var stream = countStream(10); var sum = await sumStream(stream); print(sum); // 55 } </code></pre><aside class="alert alert-info"><div class="alert-header"><i class="material-symbols" aria-hidden="true">info</i> <span>Note</span></div><div class="alert-content"><p>Click <strong>Run</strong> to see the result in the <strong>Console</strong>.</p></div></aside><div class="header-wrapper"><h2 id="error-events">Error events</h2><a class="heading-link" href="#error-events" aria-label="Link to 'Error events' section">#</a></div><p>Streams are done when there are no more events in them, and the code receiving the events is notified of this just as it is notified that a new event arrives. When reading events using an <strong>await for</strong> loop, the loops stops when the stream is done.</p><p>In some cases, an error happens before the stream is done; perhaps the network failed while fetching a file from a remote server, or perhaps the code creating the events has a bug, but someone needs to know about it.</p><p>Streams can also deliver error events like it delivers data events. Most streams will stop after the first error, but it is possible to have streams that deliver more than one error, and streams that deliver more data after an error event. In this document we only discuss streams that deliver at most one error.</p><p>When reading a stream using <strong>await for</strong>, the error is thrown by the loop statement. This ends the loop, as well. You can catch the error using <strong>try-catch</strong>. The following example throws an error when the loop iterator equals 4:</p> <?code-excerpt "misc/lib/tutorial/sum_stream_with_catch.dart"?> <pre><code data-dartpad="true" data-embed="true" data-theme="light" title="Runnable Dart sample" data-run="false">Future<int> sumStream(Stream<int> stream) async { var sum = 0; try { await for (final value in stream) { sum += value; } } catch (e) { return -1; } return sum; } Stream<int> countStream(int to) async* { for (int i = 1; i <= to; i++) { if (i == 4) { throw Exception('Intentional exception'); } else { yield i; } } } void main() async { var stream = countStream(10); var sum = await sumStream(stream); print(sum); // -1 } </code></pre><aside class="alert alert-info"><div class="alert-header"><i class="material-symbols" aria-hidden="true">info</i> <span>Note</span></div><div class="alert-content"><p>Click <strong>Run</strong> to see the result in the <strong>Console</strong>.</p></div></aside><div class="header-wrapper"><h2 id="working-with-streams">Working with streams</h2><a class="heading-link" href="#working-with-streams" aria-label="Link to 'Working with streams' section">#</a></div><p>The Stream class contains a number of helper methods that can do common operations on a stream for you, similar to the methods on an <a href="https://api.dart.dev/dart-core/Iterable-class.html">Iterable.</a> For example, you can find the last positive integer in a stream using <code>lastWhere()</code> from the Stream API.</p> <?code-excerpt "misc/lib/tutorial/misc.dart (last-positive)"?> <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">int</span><span style="color:#222222">> </span><span style="color:#6200EE">lastPositive</span><span style="color:#222222">(</span><span style="color:#0468D7">Stream</span><span style="color:#222222"><</span><span style="color:#0468D7">int</span><span style="color:#222222">> stream) =></span></span> <span class="line"><span style="color:#222222"> stream.</span><span style="color:#6200EE">lastWhere</span><span style="color:#222222">((x) => x >= </span><span style="color:#11796D">0</span><span style="color:#222222">);</span></span></code></pre></div></div><div class="header-wrapper"><h2 id="two-kinds-of-streams">Two kinds of streams</h2><a class="heading-link" href="#two-kinds-of-streams" aria-label="Link to 'Two kinds of streams' section">#</a></div><p>There are two kinds of streams.</p><div class="header-wrapper"><h3 id="single-subscription-streams">Single subscription streams</h3><a class="heading-link" href="#single-subscription-streams" aria-label="Link to 'Single subscription streams' section">#</a></div><p>The most common kind of stream contains a sequence of events that are parts of a larger whole. Events need to be delivered in the correct order and without missing any of them. This is the kind of stream you get when you read a file or receive a web request.</p><p>Such a stream can only be listened to once. Listening again later could mean missing out on initial events, and then the rest of the stream makes no sense. When you start listening, the data will be fetched and provided in chunks.</p><div class="header-wrapper"><h3 id="broadcast-streams">Broadcast streams</h3><a class="heading-link" href="#broadcast-streams" aria-label="Link to 'Broadcast streams' section">#</a></div><p>The other kind of stream is intended for individual messages that can be handled one at a time. This kind of stream can be used for mouse events in a browser, for example.</p><p>You can start listening to such a stream at any time, and you get the events that are fired while you listen. More than one listener can listen at the same time, and you can listen again later after canceling a previous subscription.</p><div class="header-wrapper"><h2 id="process-stream-methods">Methods that process a stream</h2><a class="heading-link" href="#process-stream-methods" aria-label="Link to 'Methods that process a stream' section">#</a></div><p>The following methods on <a href="https://api.dart.dev/dart-async/Stream-class.html">Stream<T></a> process the stream and return a result:</p> <?code-excerpt "misc/lib/tutorial/stream_interface.dart (main-stream-members)" remove="/^\s*Stream/"?> <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">T</span><span style="color:#222222">> </span><span style="color:#D43324">get</span><span style="color:#222222"> first;</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">bool</span><span style="color:#222222">> </span><span style="color:#D43324">get</span><span style="color:#222222"> isEmpty;</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> </span><span style="color:#D43324">get</span><span style="color:#222222"> last;</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">int</span><span style="color:#222222">> </span><span style="color:#D43324">get</span><span style="color:#222222"> length;</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> </span><span style="color:#D43324">get</span><span style="color:#222222"> single;</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">bool</span><span style="color:#222222">> </span><span style="color:#6200EE">any</span><span style="color:#222222">(</span><span style="color:#0468D7">bool</span><span style="color:#0468D7"> Function</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> element) test);</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">bool</span><span style="color:#222222">> </span><span style="color:#6200EE">contains</span><span style="color:#222222">(</span><span style="color:#0468D7">Object</span><span style="color:#222222">? needle);</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">E</span><span style="color:#222222">> </span><span style="color:#6200EE">drain</span><span style="color:#222222"><</span><span style="color:#0468D7">E</span><span style="color:#222222">>([</span><span style="color:#0468D7">E</span><span style="color:#222222">? futureValue]);</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> </span><span style="color:#6200EE">elementAt</span><span style="color:#222222">(</span><span style="color:#0468D7">int</span><span style="color:#222222"> index);</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">bool</span><span style="color:#222222">> </span><span style="color:#6200EE">every</span><span style="color:#222222">(</span><span style="color:#0468D7">bool</span><span style="color:#0468D7"> Function</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> element) test);</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> </span><span style="color:#6200EE">firstWhere</span><span style="color:#222222">(</span><span style="color:#0468D7">bool</span><span style="color:#0468D7"> Function</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> element) test, {</span><span style="color:#0468D7">T</span><span style="color:#0468D7"> Function</span><span style="color:#222222">()? orElse});</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">S</span><span style="color:#222222">> </span><span style="color:#6200EE">fold</span><span style="color:#222222"><</span><span style="color:#0468D7">S</span><span style="color:#222222">>(</span><span style="color:#0468D7">S</span><span style="color:#222222"> initialValue, </span><span style="color:#0468D7">S</span><span style="color:#0468D7"> Function</span><span style="color:#222222">(</span><span style="color:#0468D7">S</span><span style="color:#222222"> previous, </span><span style="color:#0468D7">T</span><span style="color:#222222"> element) combine);</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#6200EE"> forEach</span><span style="color:#222222">(</span><span style="color:#D43324">void</span><span style="color:#0468D7"> Function</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> element) action);</span></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">join</span><span style="color:#222222">([</span><span style="color:#0468D7">String</span><span style="color:#222222"> separator = </span><span style="color:#11796D">''</span><span style="color:#222222">]);</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> </span><span style="color:#6200EE">lastWhere</span><span style="color:#222222">(</span><span style="color:#0468D7">bool</span><span style="color:#0468D7"> Function</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> element) test, {</span><span style="color:#0468D7">T</span><span style="color:#0468D7"> Function</span><span style="color:#222222">()? orElse});</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#6200EE"> pipe</span><span style="color:#222222">(</span><span style="color:#0468D7">StreamConsumer</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> streamConsumer);</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> </span><span style="color:#6200EE">reduce</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#0468D7"> Function</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> previous, </span><span style="color:#0468D7">T</span><span style="color:#222222"> element) combine);</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> </span><span style="color:#6200EE">singleWhere</span><span style="color:#222222">(</span><span style="color:#0468D7">bool</span><span style="color:#0468D7"> Function</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> element) test, {</span><span style="color:#0468D7">T</span><span style="color:#0468D7"> Function</span><span style="color:#222222">()? orElse});</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">List</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">>> </span><span style="color:#6200EE">toList</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222"><</span><span style="color:#0468D7">Set</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">>> </span><span style="color:#6200EE">toSet</span><span style="color:#222222">();</span></span></code></pre></div></div><p>All of these functions, except <code>drain()</code> and <code>pipe()</code>, correspond to a similar function on <a href="https://api.dart.dev/dart-core/Iterable-class.html">Iterable.</a> Each one can be written easily by using an <code>async</code> function with an <strong>await for</strong> loop (or just using one of the other methods). For example, some implementations could be:</p> <?code-excerpt "misc/lib/tutorial/misc.dart (mock-stream-method-implementations)"?> <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">bool</span><span style="color:#222222">> </span><span style="color:#6200EE">contains</span><span style="color:#222222">(</span><span style="color:#0468D7">Object</span><span style="color:#222222">? needle) </span><span style="color:#D43324">async</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#D43324"> await</span><span style="color:#D43324"> for</span><span style="color:#222222"> (</span><span style="color:#D43324">final</span><span style="color:#222222"> event </span><span style="color:#D43324">in</span><span style="color:#D43324"> this</span><span style="color:#222222">) {</span></span> <span class="line"><span style="color:#D43324"> if</span><span style="color:#222222"> (event == needle) </span><span style="color:#D43324">return</span><span style="color:#11796D"> true</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#11796D"> false</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:#6200EE"> forEach</span><span style="color:#222222">(</span><span style="color:#D43324">void</span><span style="color:#0468D7"> Function</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> element) action) </span><span style="color:#D43324">async</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#D43324"> await</span><span style="color:#D43324"> for</span><span style="color:#222222"> (</span><span style="color:#D43324">final</span><span style="color:#222222"> event </span><span style="color:#D43324">in</span><span style="color:#D43324"> this</span><span style="color:#222222">) {</span></span> <span class="line"><span style="color:#6200EE"> action</span><span style="color:#222222">(event);</span></span> <span class="line"><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">List</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">>> </span><span style="color:#6200EE">toList</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"> result = <</span><span style="color:#0468D7">T</span><span style="color:#222222">>[];</span></span> <span class="line"><span style="color:#D43324"> await</span><span style="color:#6200EE"> forEach</span><span style="color:#222222">(result.add);</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#222222"> result;</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">join</span><span style="color:#222222">([</span><span style="color:#0468D7">String</span><span style="color:#222222"> separator = </span><span style="color:#11796D">''</span><span style="color:#222222">]) </span><span style="color:#D43324">async</span><span style="color:#222222"> =></span></span> <span class="line"><span style="color:#222222"> (</span><span style="color:#D43324">await</span><span style="color:#6200EE"> toList</span><span style="color:#222222">()).</span><span style="color:#6200EE">join</span><span style="color:#222222">(separator);</span></span></code></pre></div></div><p>(The actual implementations are slightly more complex, but mainly for historical reasons.)</p><div class="header-wrapper"><h2 id="modify-stream-methods">Methods that modify a stream</h2><a class="heading-link" href="#modify-stream-methods" aria-label="Link to 'Methods that modify a stream' section">#</a></div><p>The following methods on Stream return a new stream based on the original stream. Each one waits until someone listens on the new stream before listening on the original.</p> <?code-excerpt "misc/lib/tutorial/stream_interface.dart (main-stream-members)" remove="/async\w+|distinct|transform/" retain="/^\s*Stream/"?> <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">Stream</span><span style="color:#222222"><</span><span style="color:#0468D7">R</span><span style="color:#222222">> </span><span style="color:#6200EE">cast</span><span style="color:#222222"><</span><span style="color:#0468D7">R</span><span style="color:#222222">>();</span></span> <span class="line"><span style="color:#0468D7">Stream</span><span style="color:#222222"><</span><span style="color:#0468D7">S</span><span style="color:#222222">> </span><span style="color:#6200EE">expand</span><span style="color:#222222"><</span><span style="color:#0468D7">S</span><span style="color:#222222">>(</span><span style="color:#0468D7">Iterable</span><span style="color:#222222"><</span><span style="color:#0468D7">S</span><span style="color:#222222">> </span><span style="color:#0468D7">Function</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> element) convert);</span></span> <span class="line"><span style="color:#0468D7">Stream</span><span style="color:#222222"><</span><span style="color:#0468D7">S</span><span style="color:#222222">> </span><span style="color:#6200EE">map</span><span style="color:#222222"><</span><span style="color:#0468D7">S</span><span style="color:#222222">>(</span><span style="color:#0468D7">S</span><span style="color:#0468D7"> Function</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> event) convert);</span></span> <span class="line"><span style="color:#0468D7">Stream</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> </span><span style="color:#6200EE">skip</span><span style="color:#222222">(</span><span style="color:#0468D7">int</span><span style="color:#222222"> count);</span></span> <span class="line"><span style="color:#0468D7">Stream</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> </span><span style="color:#6200EE">skipWhile</span><span style="color:#222222">(</span><span style="color:#0468D7">bool</span><span style="color:#0468D7"> Function</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> element) test);</span></span> <span class="line"><span style="color:#0468D7">Stream</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> </span><span style="color:#6200EE">take</span><span style="color:#222222">(</span><span style="color:#0468D7">int</span><span style="color:#222222"> count);</span></span> <span class="line"><span style="color:#0468D7">Stream</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> </span><span style="color:#6200EE">takeWhile</span><span style="color:#222222">(</span><span style="color:#0468D7">bool</span><span style="color:#0468D7"> Function</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> element) test);</span></span> <span class="line"><span style="color:#0468D7">Stream</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> </span><span style="color:#6200EE">where</span><span style="color:#222222">(</span><span style="color:#0468D7">bool</span><span style="color:#0468D7"> Function</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> event) test);</span></span></code></pre></div></div><p>The preceding methods correspond to similar methods on <a href="https://api.dart.dev/dart-core/Iterable-class.html">Iterable</a> which transform an iterable into another iterable. All of these can be written easily using an <code>async</code> function with an <strong>await for</strong> loop.</p> <?code-excerpt "misc/lib/tutorial/stream_interface.dart (main-stream-members)" remove="/transform/" retain="/async\w+|distinct/"?> <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">Stream</span><span style="color:#222222"><</span><span style="color:#0468D7">E</span><span style="color:#222222">> </span><span style="color:#6200EE">asyncExpand</span><span style="color:#222222"><</span><span style="color:#0468D7">E</span><span style="color:#222222">>(</span><span style="color:#0468D7">Stream</span><span style="color:#222222"><</span><span style="color:#0468D7">E</span><span style="color:#222222">>? </span><span style="color:#0468D7">Function</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> event) convert);</span></span> <span class="line"><span style="color:#0468D7">Stream</span><span style="color:#222222"><</span><span style="color:#0468D7">E</span><span style="color:#222222">> </span><span style="color:#6200EE">asyncMap</span><span style="color:#222222"><</span><span style="color:#0468D7">E</span><span style="color:#222222">>(</span><span style="color:#0468D7">FutureOr</span><span style="color:#222222"><</span><span style="color:#0468D7">E</span><span style="color:#222222">> </span><span style="color:#0468D7">Function</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> event) convert);</span></span> <span class="line"><span style="color:#0468D7">Stream</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> </span><span style="color:#6200EE">distinct</span><span style="color:#222222">([</span><span style="color:#0468D7">bool</span><span style="color:#0468D7"> Function</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> previous, </span><span style="color:#0468D7">T</span><span style="color:#222222"> next)? equals]);</span></span></code></pre></div></div><p>The <code>asyncExpand()</code> and <code>asyncMap()</code> functions are similar to <code>expand()</code> and <code>map()</code>, but allow their function argument to be an asynchronous function. The <code>distinct()</code> function doesn't exist on <code>Iterable</code>, but it could have.</p> <?code-excerpt "misc/lib/tutorial/stream_interface.dart (special-stream-members)"?> <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">Stream</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> </span><span style="color:#6200EE">handleError</span><span style="color:#222222">(</span><span style="color:#0468D7">Function</span><span style="color:#222222"> onError, {</span><span style="color:#0468D7">bool</span><span style="color:#0468D7"> Function</span><span style="color:#222222">(</span><span style="color:#0468D7">dynamic</span><span style="color:#222222"> error)? test});</span></span> <span class="line"><span style="color:#0468D7">Stream</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> </span><span style="color:#6200EE">timeout</span><span style="color:#222222">(</span><span style="color:#0468D7">Duration</span><span style="color:#222222"> timeLimit,</span></span> <span class="line"><span style="color:#222222"> {</span><span style="color:#D43324">void</span><span style="color:#0468D7"> Function</span><span style="color:#222222">(</span><span style="color:#0468D7">EventSink</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> sink)? onTimeout});</span></span> <span class="line"><span style="color:#0468D7">Stream</span><span style="color:#222222"><</span><span style="color:#0468D7">S</span><span style="color:#222222">> </span><span style="color:#6200EE">transform</span><span style="color:#222222"><</span><span style="color:#0468D7">S</span><span style="color:#222222">>(</span><span style="color:#0468D7">StreamTransformer</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">, </span><span style="color:#0468D7">S</span><span style="color:#222222">> streamTransformer);</span></span></code></pre></div></div><p>The final three functions are more special. They involve error handling which an <strong>await for</strong> loop can't do鈥攖he first error reaching the loops will end the loop and its subscription on the stream. There is no recovering from that. The following code shows how to use <code>handleError()</code> to remove errors from a stream before using it in an <strong>await for</strong> loop.</p> <?code-excerpt "misc/lib/tutorial/misc.dart (map-log-errors)"?> <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">Stream</span><span style="color:#222222"><</span><span style="color:#0468D7">S</span><span style="color:#222222">> </span><span style="color:#6200EE">mapLogErrors</span><span style="color:#222222"><</span><span style="color:#0468D7">S</span><span style="color:#222222">, </span><span style="color:#0468D7">T</span><span style="color:#222222">>(</span></span> <span class="line"><span style="color:#0468D7"> Stream</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> stream,</span></span> <span class="line"><span style="color:#0468D7"> S</span><span style="color:#0468D7"> Function</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> event) convert,</span></span> <span class="line"><span style="color:#222222">) </span><span style="color:#D43324">async</span><span style="color:#222222">* {</span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> streamWithoutErrors = stream.</span><span style="color:#6200EE">handleError</span><span style="color:#222222">((e) => </span><span style="color:#6200EE">log</span><span style="color:#222222">(e));</span></span> <span class="line"><span style="color:#D43324"> await</span><span style="color:#D43324"> for</span><span style="color:#222222"> (</span><span style="color:#D43324">final</span><span style="color:#222222"> event </span><span style="color:#D43324">in</span><span style="color:#222222"> streamWithoutErrors) {</span></span> <span class="line"><span style="color:#D43324"> yield</span><span style="color:#6200EE"> convert</span><span style="color:#222222">(event);</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="transform-function">The transform() function</h3><a class="heading-link" href="#transform-function" aria-label="Link to 'The transform() function' section">#</a></div><p>The <code>transform()</code> function is not just for error handling; it is a more generalized "map" for streams. A normal map requires one value for each incoming event. However, especially for I/O streams, it might take several incoming events to produce an output event. A <a href="https://api.dart.dev/dart-async/StreamTransformer-class.html">StreamTransformer</a> can work with that. For example, decoders like <a href="https://api.dart.dev/dart-convert/Utf8Decoder-class.html">Utf8Decoder</a> are transformers. A transformer requires only one function, <a href="https://api.dart.dev/dart-async/StreamTransformer/bind.html">bind()</a>, which can be easily implemented by an <code>async</code> function.</p><div class="header-wrapper"><h3 id="reading-decoding-file">Reading and decoding a file</h3><a class="heading-link" href="#reading-decoding-file" aria-label="Link to 'Reading and decoding a file' section">#</a></div><p>The following code reads a file and runs two transforms over the stream. It first converts the data from UTF8 and then runs it through a <a href="https://api.dart.dev/dart-convert/LineSplitter-class.html">LineSplitter.</a> All lines are printed, except any that begin with a hashtag, <code>#</code>.</p> <?code-excerpt "misc/bin/cat_no_hash.dart"?> <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">import</span><span style="color:#11796D"> 'dart:convert'</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#D43324">import</span><span style="color:#11796D"> 'dart:io'</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 style="color:#0468D7">List</span><span style="color:#222222"><</span><span style="color:#0468D7">String</span><span style="color:#222222">> args) </span><span style="color:#D43324">async</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> file = </span><span style="color:#0468D7">File</span><span style="color:#222222">(args[</span><span style="color:#11796D">0</span><span style="color:#222222">]);</span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> lines = utf8.decoder</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">bind</span><span style="color:#222222">(file.</span><span style="color:#6200EE">openRead</span><span style="color:#222222">())</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">transform</span><span style="color:#222222">(</span><span style="color:#D43324">const</span><span style="color:#0468D7"> LineSplitter</span><span style="color:#222222">());</span></span> <span class="line"><span style="color:#D43324"> await</span><span style="color:#D43324"> for</span><span style="color:#222222"> (</span><span style="color:#D43324">final</span><span style="color:#222222"> line </span><span style="color:#D43324">in</span><span style="color:#222222"> lines) {</span></span> <span class="line"><span style="color:#D43324"> if</span><span style="color:#222222"> (!line.</span><span style="color:#6200EE">startsWith</span><span style="color:#222222">(</span><span style="color:#11796D">'#'</span><span style="color:#222222">)) </span><span style="color:#6200EE">print</span><span style="color:#222222">(line);</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h2 id="listen-method">The listen() method</h2><a class="heading-link" href="#listen-method" aria-label="Link to 'The listen() method' section">#</a></div><p>The final method on Stream is <code>listen()</code>. This is a "low-level" method鈥攁ll other stream functions are defined in terms of <code>listen()</code>.</p> <?code-excerpt "misc/lib/tutorial/stream_interface.dart (listen)"?> <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">StreamSubscription</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> </span><span style="color:#6200EE">listen</span><span style="color:#222222">(</span><span style="color:#D43324">void</span><span style="color:#0468D7"> Function</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> event)? onData,</span></span> <span class="line"><span style="color:#222222"> {</span><span style="color:#0468D7">Function</span><span style="color:#222222">? onError, </span><span style="color:#D43324">void</span><span style="color:#0468D7"> Function</span><span style="color:#222222">()? onDone, </span><span style="color:#0468D7">bool</span><span style="color:#222222">? cancelOnError});</span></span></code></pre></div></div><p>To create a new <code>Stream</code> type, you can just extend the <code>Stream</code> class and implement the <code>listen()</code> method鈥攁ll other methods on <code>Stream</code> call <code>listen()</code> in order to work.</p><p>The <code>listen()</code> method allows you to start listening on a stream. Until you do so, the stream is an inert object describing what events you want to see. When you listen, a <a href="https://api.dart.dev/dart-async/StreamSubscription-class.html">StreamSubscription</a> object is returned which represents the active stream producing events. This is similar to how an <code>Iterable</code> is just a collection of objects, but the iterator is the one doing the actual iteration.</p><p>The stream subscription allows you to pause the subscription, resume it after a pause, and cancel it completely. You can set callbacks to be called for each data event or error event, and when the stream is closed.</p><div class="header-wrapper"><h2 id="other-resources">Other resources</h2><a class="heading-link" href="#other-resources" aria-label="Link to 'Other resources' section">#</a></div><p>Read the following documentation for more details on using streams and asynchronous programming in Dart.</p><ul><li><a href="/libraries/async/creating-streams">Creating Streams in Dart</a>, an article about creating your own streams</li><li><a href="/libraries/async/futures-error-handling">Futures and Error Handling</a>, an article that explains how to handle errors using the Future API</li><li><a href="/language/async">Asynchrony support</a>, a section in the <a href="/language">language tour</a></li><li><a href="https://api.dart.dev/dart-async/Stream-class.html">Stream API reference</a></li></ul><p id="page-github-links"><span>Unless stated otherwise, the documentation on this site reflects Dart 3.5.4. Page last updated on 2024-11-17.</span> <a href="https://github.com/dart-lang/site-www/tree/main/src/content/libraries/async/using-streams.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/using-streams/&page-source=https://github.com/dart-lang/site-www/tree/main/src/content/libraries/async/using-streams.md" title="Report an issue with this page" target="_blank" rel="noopener">report an issue</a>.</p></div></article></main><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="Medium blog"><svg><use href="/assets/img/social/medium.svg#medium"></use></svg> </a><a href="https://github.com/dart-lang" target="_blank" rel="noopener" title="GitHub"><svg><use href="/assets/img/social/github.svg#github"></use></svg> </a><a href="https://twitter.com/dart_lang" target="_blank" rel="noopener" title="X (Twitter)"><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></body></html>