Movatterモバイル変換


[0]ホーム

URL:


Skip to main content

dart.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic.

Learn more
dart:async

Dart 3.10 is taking off with dot shorthands, stable build hooks, nuanced deprecation annotations, and more!Learn more

Asynchronous programming often uses callback functions, but Dart provides alternatives:Future andStream objects. A Future is like a promise for a result to be provided sometime in the future. A Stream is a way to get a sequence of values, such as events. Future, Stream, and more are in the dart:async library (API reference).

Note

The dart:async library works in both web apps and command-line apps. To use it, import dart:async:

dart
import'dart:async';
Tip

You don't need to import dart:async to use the Future and Stream APIs, because dart:core exports those classes.

Future objects appear throughout the Dart libraries, often as the object returned by an asynchronous method. When a futurecompletes, its value is ready to use.

Using await

#

Before you directly use the Future API, consider usingawait instead. Code that usesawait expressions can be easier to understand than code that uses the Future API.

Consider the following function. It uses Future'sthen() method to execute three asynchronous functions in a row, waiting for each one to complete before executing the next one.

dart
voidrunUsingFuture(){// ...findEntryPoint().then((entryPoint){returnrunExecutable(entryPoint,args);}).then(flushThenExit);}

The equivalent code with await expressions looks more like synchronous code:

dart
Future<void>runUsingAsyncAwait()async{// ...varentryPoint=awaitfindEntryPoint();varexitCode=awaitrunExecutable(entryPoint,args);awaitflushThenExit(exitCode);}

Anasync function can catch exceptions from Futures. For example:

dart
varentryPoint=awaitfindEntryPoint();try{varexitCode=awaitrunExecutable(entryPoint,args);awaitflushThenExit(exitCode);}catch(e){// Handle the error...}
Important

Async functions return Futures. If you don't want your function to return a future, then use a different solution. For example, you might call anasync function from your function.

For more information on usingawait and related Dart language features, see theasynchronous programming tutorial.

Basic usage

#

You can usethen() to schedule code that runs when the future completes. For example,Client.read() returns a Future, since HTTP requests can take a while. Usingthen() lets you run some code when that Future has completed and the promised string value is available:

dart
httpClient.read(url).then((Stringresult){print(result);});

UsecatchError() to handle any errors or exceptions that a Future object might throw.

dart
httpClient.read(url).then((Stringresult){print(result);}).catchError((e){// Handle or ignore the error.});

Thethen().catchError() pattern is the asynchronous version oftry-catch.

Important

Be sure to invokecatchError() on the result ofthen()—not on the result of the originalFuture. Otherwise, thecatchError() can handle errors only from the original Future's computation, but not from the handler registered bythen().

Thethen() method returns a Future, providing a useful way to run multiple asynchronous functions in a certain order. If the callback registered withthen() returns a Future,then() returns a Future that will complete with the same result as the Future returned from the callback. If the callback returns a value of any other type,then() creates a new Future that completes with the value.

dart
Futureresult=costlyQuery(url);result.then((value)=>expensiveWork(value)).then((_)=>lengthyComputation()).then((_)=>print('Done!')).catchError((exception){/* Handle exception...*/});

In the preceding example, the methods run in the following order:

  1. costlyQuery()
  2. expensiveWork()
  3. lengthyComputation()

Here is the same code written using await:

dart
try{finalvalue=awaitcostlyQuery(url);awaitexpensiveWork(value);awaitlengthyComputation();print('Done!');}catch(e){/* Handle exception...*/}

Waiting for multiple futures

#

Sometimes your algorithm needs to invoke many asynchronous functions and wait for them all to complete before continuing. Use theFuture.wait() static method to manage multiple Futures and wait for them to complete:

dart
Future<void>deleteLotsOfFiles()async=>...Future<void>copyLotsOfFiles()async=>...Future<void>checksumLotsOfOtherFiles()async=>...awaitFuture.wait([deleteLotsOfFiles(),copyLotsOfFiles(),checksumLotsOfOtherFiles(),]);print('Done with all the long steps!');

Future.wait() returns a future which completes once all the provided futures have completed. It completes either with their results, or with an error if any of the provided futures fail.

Handling errors for multiple futures

#

You can also wait for parallel operations on:

These extensions return aFuture with the resulting values of all provided futures. UnlikeFuture.wait, they also let you handle errors.

If any future in the collection completes with an error,wait completes with aParallelWaitError. This allows the caller to handle individual errors and dispose of successful results if necessary.

When youdon't need the result values from each future, usewait on aniterable of futures:

dart
Future<int>delete()async=>...;Future<String>copy()async=>...;Future<bool>errorResult()async=>...;voidmain()async{try{// Wait for each future in a list, returns a list of futures:varresults=await[delete(),copy(),errorResult()].wait;}onParallelWaitError<List<bool?>,List<AsyncError?>>catch(e){print(e.values[0]);// Prints successful futureprint(e.values[1]);// Prints successful futureprint(e.values[2]);// Prints null when the result is an errorprint(e.errors[0]);// Prints null when the result is successfulprint(e.errors[1]);// Prints null when the result is successfulprint(e.errors[2]);// Prints error}}

When youdo need the individual result values from each future, usewait on arecord of futures. This provides the additional benefit that the futures can be of different types:

dart
Future<int>delete()async=>...;Future<String>copy()async=>...;Future<bool>errorResult()async=>...;voidmain()async{try{// Wait for each future in a record.// Returns a record of futures that you can destructure.final(deleteInt,copyString,errorBool)=await(delete(),copy(),errorResult()).wait;// Do something with the results...}onParallelWaitError<(int?,String?,bool?),(AsyncError?,AsyncError?,AsyncError?)>catch(e){// ...}}

Stream

#

Stream objects appear throughout Dart APIs, representing sequences of data. For example, HTML events such as button clicks are delivered using streams. You can also read a file as a stream.

Using an asynchronous for loop

#

Sometimes you can use an asynchronous for loop (await for) instead of using the Stream API.

Consider the following function. It uses Stream'slisten() method to subscribe to a list of files, passing in a function literal that searches each file or directory.

dart
voidmain(List<String>arguments){// ...FileSystemEntity.isDirectory(searchPath).then((isDir){if(isDir){finalstartingDir=Directory(searchPath);startingDir.list().listen((entity){if(entityisFile){searchFile(entity,searchTerms);}});}else{searchFile(File(searchPath),searchTerms);}});}

The equivalent code with await expressions, including an asynchronous for loop (await for), looks more like synchronous code:

dart
voidmain(List<String>arguments)async{// ...if(awaitFileSystemEntity.isDirectory(searchPath)){finalstartingDir=Directory(searchPath);awaitfor(finalentityinstartingDir.list()){if(entityisFile){searchFile(entity,searchTerms);}}}else{searchFile(File(searchPath),searchTerms);}}
Important

Before usingawait for, make sure that it makes the code clearer and that you really do want to wait for all of the stream's results. For example, you usually shouldnot useawait for for DOM event listeners, because the DOM sends endless streams of events. If you useawait for to register two DOM event listeners in a row, then the second kind of event is never handled.

For more information on usingawait and related Dart language features, see theasynchronous programming tutorial.

Listening for stream data

#

To get each value as it arrives, either useawait for or subscribe to the stream using thelisten() method:

dart
// Add an event handler to a button.submitButton.onClick.listen((e){// When the button is clicked, it runs this code.submitData();});

In this example, theonClick property is aStream object provided by the submit button.

If you care about only one event, you can get it using a property such asfirst,last, orsingle. To test the event before handling it, use a method such asfirstWhere(),lastWhere(), orsingleWhere().

If you care about a subset of events, you can use methods such asskip(),skipWhile(),take(),takeWhile(), andwhere().

Transforming stream data

#

Often, you need to change the format of a stream's data before you can use it. Use thetransform() method to produce a stream with a different type of data:

dart
varlines=inputStream.transform(utf8.decoder).transform(constLineSplitter());

This example uses two transformers. First it uses utf8.decoder to transform the stream of integers into a stream of strings. Then it uses a LineSplitter to transform the stream of strings into a stream of separate lines. These transformers are from the dart:convert library (see thedart:convert section).

Handling errors and completion

#

How you specify error and completion handling code depends on whether you use an asynchronous for loop (await for) or the Stream API.

If you use an asynchronous for loop, then use try-catch to handle errors. Code that executes after the stream is closed goes after the asynchronous for loop.

dart
Future<void>readFileAwaitFor()async{varconfig=File('config.txt');Stream<List<int>>inputStream=config.openRead();varlines=inputStream.transform(utf8.decoder).transform(constLineSplitter());try{awaitfor(finallineinlines){print('Got${line.length} characters from stream');}print('file is now closed');}catch(e){print(e);}}

If you use the Stream API, then handle errors by registering anonError listener. Run code after the stream is closed by registering anonDone listener.

dart
varconfig=File('config.txt');Stream<List<int>>inputStream=config.openRead();inputStream.transform(utf8.decoder).transform(constLineSplitter()).listen((Stringline){print('Got${line.length} characters from stream');},onDone:(){print('file is now closed');},onError:(e){print(e);},);

More information

#

For some examples of using Future and Stream in command-line apps, check out thedart:io documentation. Also see these articles and tutorials:

Was this page's content helpful?

Unless stated otherwise, the documentation on this site reflects Dart 3.10.0. Page last updated on 2025-5-5.View source orreport an issue.


[8]ページ先頭

©2009-2025 Movatter.jp