OLD | NEW |
1 --- | 1 --- |
2 layout: article | 2 layout: default |
3 title: "Using Future Based APIs" | 3 title: "Use Future-Based APIs" |
4 description: "A first look at Futures and how to use them to make your | 4 description: "A first look at Futures and how to use them to make your asynchron
ous code better." |
5 asynchronous code better." | 5 has-permalinks: true |
| 6 tutorial: |
| 7 id: futures |
| 8 next: fetchdata/ |
| 9 next-title: "Fetch Data Dynamically" |
| 10 prev: polymer-intro/ |
| 11 prev-title: "Define a Custom Element" |
6 rel: | 12 rel: |
7 author: shailen-tuli | 13 author: shailen-tuli |
8 has-permalinks: true | |
9 article: | |
10 written_on: 2013-02-07 | |
11 collection: libraries-and-apis | |
12 --- | 14 --- |
13 | 15 |
14 {% include toc.html %} | 16 {% capture whats_the_point %} |
15 | 17 |
16 # {{ page.title }} | 18 * Dart is single-threaded. |
| 19 * Synchronous code can make your program freeze. |
| 20 * Use Futures to perform asynchronous operations. |
| 21 * Call `then()` to schedule code that runs when a Future completes. |
| 22 * Use `catchError()` to handle errors that occur within a Future. |
| 23 * You can chain Futures to run asynchronous functions in order. |
17 | 24 |
18 _Written by Shailen Tuli, February 2013_ | 25 {% endcapture %} |
19 | 26 |
20 ## Introduction | 27 {% capture sample_links %} |
21 | 28 |
22 Dart is a single-threaded programming language. If any code blocks the thread | 29 |
23 of execution, the program effectively freezes. Let's look at some code where | 30 <p markdown="1"> This tutorial features these examples |
24 this happens: | 31 in the `bin` directory, |
| 32 all variations of the same example:</p> |
| 33 |
| 34 * futures1 |
| 35 * futures2 |
| 36 * futures3 |
| 37 * futures4 |
| 38 * futures5 |
| 39 |
| 40 <p> |
| 41 Don't have the source code? |
| 42 <a href="https://github.com/dart-lang/dart-tutorials-samples/archive/master.zip"
> |
| 43 Download it. |
| 44 </a> |
| 45 |
| 46 {% endcapture %} |
| 47 |
| 48 {% capture content %} |
| 49 |
| 50 |
| 51 <div class="tute-target-title"> |
| 52 <h1>{{page.title}}</h1> |
| 53 <h3>Use Futures for asynchronous operations.</h3> |
| 54 </div> |
| 55 |
| 56 _Written by Shailen Tuli_ |
| 57 |
| 58 Dart is a single-threaded programming language. |
| 59 If any code blocks the thread of execution |
| 60 (for example, by waiting for a time-consuming operation |
| 61 or blocking on I/O) |
| 62 the program effectively freezes. |
| 63 Asynchronous operations let your program run without getting blocked. |
| 64 Dart uses Futures to perform asynchronous operations. |
| 65 |
| 66 * [Introduction](#introduction) |
| 67 * [What is a Future?](#what-is-a-future) |
| 68 * [Using a Future](#using-a-future) |
| 69 * [Sequence of events during code execution](#sequence-of-events) |
| 70 * [Handling errors when dealing with Futures](#handling-errors) |
| 71 * [Calling multiple functions that return Futures](#calling-multiple-funcs) |
| 72 * [Other resources](#other-resources) |
| 73 * [What next?](#what-next) |
| 74 |
| 75 ## Introduction {#introduction} |
| 76 |
| 77 Let's look at some code that could possibly cause a program to freeze: |
25 | 78 |
26 {% prettify dart %} | 79 {% prettify dart %} |
27 import 'dart:io'; | 80 import 'dart:io'; |
28 | 81 |
29 void printDailyNewsDigest() { | 82 void printDailyNewsDigest() { |
30 File file = new File("dailyNewsDigest.txt"); | 83 File file = new File("dailyNewsDigest.txt"); |
31 print(file.readAsStringSync()); | 84 print(file.readAsStringSync()); |
32 } | 85 } |
33 | 86 |
34 void main() { | 87 void main() { |
(...skipping 13 matching lines...) Expand all Loading... |
48 Baseball score: Red Sox 10, Yankees 0 | 101 Baseball score: Red Sox 10, Yankees 0 |
49 | 102 |
50 Our code is problematic: since `readAsStringSync()` blocks, the remaining code | 103 Our code is problematic: since `readAsStringSync()` blocks, the remaining code |
51 runs only when `readAsStringSync()` returns with the contents of the file, | 104 runs only when `readAsStringSync()` returns with the contents of the file, |
52 _however long that takes_. And if reading the file takes a long time, the | 105 _however long that takes_. And if reading the file takes a long time, the |
53 user waits passively, wondering if she won the lottery, what tomorrow's weather | 106 user waits passively, wondering if she won the lottery, what tomorrow's weather |
54 will be like, and who won today's game. Not good. | 107 will be like, and who won today's game. Not good. |
55 | 108 |
56 To help keep the application responsive, Dart library authors use an | 109 To help keep the application responsive, Dart library authors use an |
57 asynchronous model when defining functions that do potentially expensive work. | 110 asynchronous model when defining functions that do potentially expensive work. |
58 Such functions return their value using a Future. | 111 Such functions return their value using a |
| 112 <a href="https://api.dartlang.org/dart_async/Future.html" |
| 113 target="_blank">Future</a> |
59 | 114 |
60 ## What is a Future? | 115 ## What is a Future? {#what-is-a-future} |
61 | 116 |
62 A Future represents a means for getting a value sometime in the future. When a | 117 A Future represents a means for getting a value sometime in the future. When a |
63 function that returns a Future is invoked, two things happen: | 118 function that returns a Future is invoked, two things happen: |
64 | 119 |
65 1. The function queues up work to be done and returns an uncompleted Future | 120 1. The function queues up work to be done and returns an uncompleted Future |
66 object immediately. | 121 object immediately. |
67 1. Later, when a value is available, the Future object completes with that | 122 1. Later, when a value is available, the Future object completes with that |
68 value (or with an error; we'll discuss that later). | 123 value (or with an error; we'll discuss that later). |
69 | 124 |
70 To get the value that the Future represents, use the `then()` method to | 125 To get the value that the Future represents, use the `then()` method to |
71 register a callback. This callback fires when the Future completes. | 126 register a callback. This callback fires when the Future completes. |
72 | 127 |
73 ## Using a Future | 128 ## Using a Future {#using-a-future} |
74 | 129 |
75 Let's rewrite `printDailyNewsDigest()` to get the file contents | 130 Let's rewrite `printDailyNewsDigest()` to get the file contents |
76 asynchronously: | 131 asynchronously: |
77 | 132 |
78 {% prettify dart %} | 133 {% prettify dart %} |
79 import 'dart:io'; | 134 import 'dart:io'; |
80 import 'dart:async'; | 135 import 'dart:async'; |
81 | 136 |
82 void printDailyNewsDigest() { | 137 void printDailyNewsDigest() { |
83 File file = new File("dailyNewsDigest.txt"); | 138 File file = new File("dailyNewsDigest.txt"); |
(...skipping 11 matching lines...) Expand all Loading... |
95 `readAsString()` finishes reading the news file, the program prints its | 150 `readAsString()` finishes reading the news file, the program prints its |
96 contents. If `readAsString()` takes a little while to complete its work, no | 151 contents. If `readAsString()` takes a little while to complete its work, no |
97 great harm is done: the user gets to read other things before the daily news | 152 great harm is done: the user gets to read other things before the daily news |
98 digest is printed. | 153 digest is printed. |
99 | 154 |
100 Winning lotto numbers: [23, 63, 87, 26, 2] | 155 Winning lotto numbers: [23, 63, 87, 26, 2] |
101 Tomorrow's forecast: 70F, sunny. | 156 Tomorrow's forecast: 70F, sunny. |
102 Baseball score: Red Sox 10, Yankees 0 | 157 Baseball score: Red Sox 10, Yankees 0 |
103 <Contents of dailyNewsDigest.txt> | 158 <Contents of dailyNewsDigest.txt> |
104 | 159 |
105 ## Sequence of events during code execution | 160 ## Sequence of events during code execution {#sequence-of-events} |
106 | 161 |
107 The preceding code executes in three steps: | 162 The preceding code executes in three steps: |
108 | 163 |
109 1. The program enters `main()`, which calls `printDailyNewsDigest()`, which | 164 1. The program enters `main()`, which calls `printDailyNewsDigest()`, which |
110 queues up the file reading task. After calling the remaining print functions, | 165 queues up the file reading task. After calling the remaining print functions, |
111 `main()` exits, but the program continues. | 166 `main()` exits, but the program continues. |
112 1. The work scheduled by `readAsString()` is performed, and the contents of the | 167 1. The work scheduled by `readAsString()` is performed, and the contents of the |
113 file are read into memory. When the entire file is read, the Future completes | 168 file are read into memory. When the entire file is read, the Future completes |
114 with the file contents. | 169 with the file contents. |
115 1. The callback registered within `then()` fires and prints the contents | 170 1. The callback registered within `then()` fires and prints the contents |
116 of the news file. | 171 of the news file. |
117 | 172 |
118 Calling `then()` returns a new Future, which completes with the value | 173 Calling `then()` returns a new Future, which completes with the value |
119 returned by `then()`'s callback. This means that calls to `then()` can be | 174 returned by `then()`'s callback. This means that calls to `then()` can be |
120 chained (we'll see examples of this later). | 175 chained (we'll see examples of this later). |
121 | 176 |
122 ## Handling errors when dealing with Futures | 177 ## Handling errors when dealing with Futures {#handling-errors} |
123 | 178 |
124 If a Future-returning function completes with an error, the Future returned by | 179 If a Future-returning function completes with an error, the Future returned by |
125 `then()` also completes with an error. We can capture that error using | 180 `then()` also completes with an error. We can capture that error using |
126 `catchError()`: | 181 `catchError()`: |
127 | 182 |
128 {% prettify dart %} | 183 {% prettify dart %} |
129 | 184 |
130 void printDailyNewsDigest() { | 185 void printDailyNewsDigest() { |
131 File file = new File("dailyNewsDigest.txt"); | 186 File file = new File("dailyNewsDigest.txt"); |
132 Future future = file.readAsString(); | 187 Future future = file.readAsString(); |
(...skipping 18 matching lines...) Expand all Loading... |
151 </strong> | 206 </strong> |
152 </aside> | 207 </aside> |
153 | 208 |
154 Like `then()`, `catchError()` returns a new Future that completes with | 209 Like `then()`, `catchError()` returns a new Future that completes with |
155 the return value of its callback. | 210 the return value of its callback. |
156 | 211 |
157 For more details and examples, read | 212 For more details and examples, read |
158 [Futures and Error Handling](/articles/futures-and-error-handling/). | 213 [Futures and Error Handling](/articles/futures-and-error-handling/). |
159 | 214 |
160 | 215 |
161 ## Calling multiple functions that return Futures | 216 ## Calling multiple functions that return Futures {#calling-multiple-funcs} |
162 | 217 |
163 Consider three functions, `expensiveA()`, `expensiveB()`, and `expensiveC()`, | 218 Consider three functions, `expensiveA()`, `expensiveB()`, and `expensiveC()`, |
164 that return Futures. You can invoke them sequentially (one function starts | 219 that return Futures. You can invoke them sequentially (one function starts |
165 when a previous one completes), or you can kick off all of them at the same | 220 when a previous one completes), or you can kick off all of them at the same |
166 time and do something once all the values return. The Future interface | 221 time and do something once all the values return. The Future interface |
167 is fluid enough to deal with both use cases. | 222 is fluid enough to deal with both use cases. |
168 | 223 |
169 ### Chaining function calls using then() | 224 ### Chaining function calls using then() |
170 | 225 |
171 When Future-returning functions need to run in order, use | 226 When Future-returning functions need to run in order, use |
(...skipping 21 matching lines...) Expand all Loading... |
193 {% prettify dart %} | 248 {% prettify dart %} |
194 Future.wait([expensiveA(), expensiveB(), expensiveC()]) | 249 Future.wait([expensiveA(), expensiveB(), expensiveC()]) |
195 .then((List responses) => chooseBestResponse(responses)) | 250 .then((List responses) => chooseBestResponse(responses)) |
196 .catchError((e) => handleError(e)); | 251 .catchError((e) => handleError(e)); |
197 {% endprettify %} | 252 {% endprettify %} |
198 | 253 |
199 If any of the invoked functions completes with an error, the Future returned | 254 If any of the invoked functions completes with an error, the Future returned |
200 by `Future.wait()` also completes with an error. Use `catchError()` to handle | 255 by `Future.wait()` also completes with an error. Use `catchError()` to handle |
201 the error. | 256 the error. |
202 | 257 |
203 ## More information | 258 ## Other resources {#other-resources} |
204 | 259 |
205 Read the following documentation for more details on using Futures: | 260 Read the following documentation for more details on using Futures: |
206 | 261 |
207 * [Futures and Error Handling](/articles/futures-and-error-handling/), | 262 * [Futures and Error Handling](/articles/futures-and-error-handling/), |
208 an article that starts where this one ends | 263 an article that starts where this tutorial ends |
209 * [The Event Loop and Dart](/articles/event-loop/), | 264 * [The Event Loop and Dart](/articles/event-loop/), |
210 an article that describes how to schedule tasks using Futures | 265 an article that describes how to schedule tasks using Futures |
211 * [Future API reference](http://api.dartlang.org/dart_async/Future.html) | 266 * [Future API reference](http://api.dartlang.org/dart_async/Future.html) |
212 | 267 |
| 268 ## What next? {#what-next} |
| 269 |
| 270 * The next tutorial, |
| 271 [Fetch Data Dynamically](/docs/tutorials/fetchdata/), |
| 272 uses a Future when doing an HTTP request. |
| 273 |
| 274 * The example featured in |
| 275 [Use IndexedDB](/docs/tutorials/indexeddb/) |
| 276 uses many Futures when interacting with the database. |
| 277 |
| 278 {% endcapture %} |
| 279 |
| 280 {% include tutorial.html %} |
| 281 |
OLD | NEW |