Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(251)

Side by Side Diff: sdk/lib/async/stream.dart

Issue 11862008: Make Streams also cosider a thrown AsyncError a rethrow. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix indentation. Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | sdk/lib/async/stream_controller.dart » ('j') | sdk/lib/async/stream_pipe.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of dart.async; 5 part of dart.async;
6 6
7 // ------------------------------------------------------------------- 7 // -------------------------------------------------------------------
8 // Core Stream types 8 // Core Stream types
9 // ------------------------------------------------------------------- 9 // -------------------------------------------------------------------
10 10
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 * Create a new stream that converts each element of this stream 103 * Create a new stream that converts each element of this stream
104 * to a new value using the [convert] function. 104 * to a new value using the [convert] function.
105 */ 105 */
106 Stream mappedBy(convert(T event)) { 106 Stream mappedBy(convert(T event)) {
107 return this.transform(new MapStream<T, dynamic>(convert)); 107 return this.transform(new MapStream<T, dynamic>(convert));
108 } 108 }
109 109
110 /** 110 /**
111 * Create a wrapper Stream that intercepts some errors from this stream. 111 * Create a wrapper Stream that intercepts some errors from this stream.
112 * 112 *
113 * If the handler returns null, the error is considered handled. 113 * If this stream sends an error that matches [test], then it is intercepted
114 * Otherwise the returned [AsyncError] is passed to the subscribers 114 * by the [handle] function.
115 * of the stream. 115 *
116 * An [AsyncError] [:e:] is matched by a test function if [:test(e):] returns
117 * true. If [test] is omitted, evert error is considered mathcing.
floitsch 2013/01/11 13:23:33 every ... matching
Lasse Reichstein Nielsen 2013/01/14 08:33:30 Done.
118 *
119 * If the error is intercepted, the [handle] function can decide what to do
120 * with it. It can throw if it wants to raise a new (or the same) error,
121 * or simply return to make the stream forget the error.
116 */ 122 */
117 Stream handleError(AsyncError handle(AsyncError error)) { 123 Stream<T> handleError(void handle(AsyncError error), { bool test(error) }) {
118 return this.transform(new HandleErrorStream<T>(handle)); 124 return this.transform(new HandleErrorStream<T>(handle, test));
119 } 125 }
120 126
121 /** 127 /**
122 * Create a new stream from this stream that converts each element 128 * Create a new stream from this stream that converts each element
123 * into zero or more events. 129 * into zero or more events.
124 * 130 *
125 * Each incoming event is converted to an [Iterable] of new events, 131 * Each incoming event is converted to an [Iterable] of new events,
126 * and each of these new events are then sent by the returned stream 132 * and each of these new events are then sent by the returned stream
127 * in order. 133 * in order.
128 */ 134 */
(...skipping 20 matching lines...) Expand all
149 155
150 /** Reduces a sequence of values by repeatedly applying [combine]. */ 156 /** Reduces a sequence of values by repeatedly applying [combine]. */
151 Future reduce(var initialValue, combine(var previous, T element)) { 157 Future reduce(var initialValue, combine(var previous, T element)) {
152 _FutureImpl result = new _FutureImpl(); 158 _FutureImpl result = new _FutureImpl();
153 var value = initialValue; 159 var value = initialValue;
154 StreamSubscription subscription; 160 StreamSubscription subscription;
155 subscription = this.listen( 161 subscription = this.listen(
156 (T element) { 162 (T element) {
157 try { 163 try {
158 value = combine(value, element); 164 value = combine(value, element);
165 } on AsyncError catch (e) {
166 subscription.cancel();
167 result._setError(e);
159 } catch (e, s) { 168 } catch (e, s) {
160 subscription.cancel(); 169 subscription.cancel();
161 result._setError(new AsyncError(e, s)); 170 result._setError(new AsyncError(e, s));
162 } 171 }
163 }, 172 },
164 onError: (AsyncError e) { 173 onError: (AsyncError e) {
165 result._setError(e); 174 result._setError(e);
166 }, 175 },
167 onDone: () { 176 onDone: () {
168 result._setValue(value); 177 result._setValue(value);
(...skipping 23 matching lines...) Expand all
192 * Check whether [match] occurs in the elements provided by this stream. 201 * Check whether [match] occurs in the elements provided by this stream.
193 * 202 *
194 * Completes the [Future] when the answer is known. 203 * Completes the [Future] when the answer is known.
195 * If this stream reports an error, the [Future] will report that error. 204 * If this stream reports an error, the [Future] will report that error.
196 */ 205 */
197 Future<bool> contains(T match) { 206 Future<bool> contains(T match) {
198 _FutureImpl<bool> future = new _FutureImpl<bool>(); 207 _FutureImpl<bool> future = new _FutureImpl<bool>();
199 StreamSubscription subscription; 208 StreamSubscription subscription;
200 subscription = this.listen( 209 subscription = this.listen(
201 (T element) { 210 (T element) {
202 if (element == match) { 211 bool matches;
212 try {
213 matches = (element == match);
214 } on AsyncError catch (e) {
floitsch 2013/01/11 13:23:33 This is repeated too often... runUserCode(userCode
Lasse Reichstein Nielsen 2013/01/14 08:33:30 Done. It's not pretty, but it's a little smaller
215 subscription.cancel();
216 future._setError(e);
217 return;
218 } catch (e, s) {
219 subscription.cancel();
220 future._setError(new AsyncError(e, s));
221 return;
222 }
223 if (matches) {
203 subscription.cancel(); 224 subscription.cancel();
204 future._setValue(true); 225 future._setValue(true);
205 } 226 }
206 }, 227 },
207 onError: future._setError, 228 onError: future._setError,
208 onDone: () { 229 onDone: () {
209 future._setValue(false); 230 future._setValue(false);
210 }, 231 },
211 unsubscribeOnError: true); 232 unsubscribeOnError: true);
212 return future; 233 return future;
213 } 234 }
214 235
215 /** 236 /**
216 * Check whether [test] accepts all elements provided by this stream. 237 * Check whether [test] accepts all elements provided by this stream.
217 * 238 *
218 * Completes the [Future] when the answer is known. 239 * Completes the [Future] when the answer is known.
219 * If this stream reports an error, the [Future] will report that error. 240 * If this stream reports an error, the [Future] will report that error.
220 */ 241 */
221 Future<bool> every(bool test(T element)) { 242 Future<bool> every(bool test(T element)) {
222 _FutureImpl<bool> future = new _FutureImpl<bool>(); 243 _FutureImpl<bool> future = new _FutureImpl<bool>();
223 StreamSubscription subscription; 244 StreamSubscription subscription;
224 subscription = this.listen( 245 subscription = this.listen(
225 (T element) { 246 (T element) {
226 if (!test(element)) { 247 bool matches;
248 try {
249 matches = test(element);
250 } on AsyncError catch (e) {
251 subscription.cancel();
252 future._setError(e);
253 return;
254 } catch (e, s) {
255 subscription.cancel();
256 future._setError(new AsyncError(e, s));
257 return;
258 }
259 if (!matches) {
227 subscription.cancel(); 260 subscription.cancel();
228 future._setValue(false); 261 future._setValue(false);
229 } 262 }
230 }, 263 },
231 onError: future._setError, 264 onError: future._setError,
232 onDone: () { 265 onDone: () {
233 future._setValue(true); 266 future._setValue(true);
234 }, 267 },
235 unsubscribeOnError: true); 268 unsubscribeOnError: true);
236 return future; 269 return future;
237 } 270 }
238 271
239 /** 272 /**
240 * Check whether [test] accepts any element provided by this stream. 273 * Check whether [test] accepts any element provided by this stream.
241 * 274 *
242 * Completes the [Future] when the answer is known. 275 * Completes the [Future] when the answer is known.
243 * If this stream reports an error, the [Future] will report that error. 276 * If this stream reports an error, the [Future] will report that error.
244 */ 277 */
245 Future<bool> any(bool test(T element)) { 278 Future<bool> any(bool test(T element)) {
246 _FutureImpl<bool> future = new _FutureImpl<bool>(); 279 _FutureImpl<bool> future = new _FutureImpl<bool>();
247 StreamSubscription subscription; 280 StreamSubscription subscription;
248 subscription = this.listen( 281 subscription = this.listen(
249 (T element) { 282 (T element) {
250 if (test(element)) { 283 bool matches;
284 try {
285 matches = test(element);
286 } on AsyncError catch (e) {
287 subscription.cancel();
288 future._setError(e);
289 return;
290 } catch (e, s) {
291 subscription.cancel();
292 future._setError(new AsyncError(e, s));
293 return;
294 }
295 if (matches) {
251 subscription.cancel(); 296 subscription.cancel();
252 future._setValue(true); 297 future._setValue(true);
253 } 298 }
254 }, 299 },
255 onError: future._setError, 300 onError: future._setError,
256 onDone: () { 301 onDone: () {
257 future._setValue(false); 302 future._setValue(false);
258 }, 303 },
259 unsubscribeOnError: true); 304 unsubscribeOnError: true);
260 return future; 305 return future;
(...skipping 26 matching lines...) Expand all
287 */ 332 */
288 Future<T> min([int compare(T a, T b)]) { 333 Future<T> min([int compare(T a, T b)]) {
289 if (compare == null) compare = Comparable.compare; 334 if (compare == null) compare = Comparable.compare;
290 _FutureImpl<T> future = new _FutureImpl<T>(); 335 _FutureImpl<T> future = new _FutureImpl<T>();
291 StreamSubscription subscription; 336 StreamSubscription subscription;
292 T min = null; 337 T min = null;
293 subscription = this.listen( 338 subscription = this.listen(
294 (T value) { 339 (T value) {
295 min = value; 340 min = value;
296 subscription.onData((T value) { 341 subscription.onData((T value) {
297 if (compare(min, value) > 0) min = value; 342 bool foundSmaller;
343 try {
344 foundSmaller = (compare(min, value) > 0);
345 } on AsyncError catch (e) {
346 subscription.cancel();
347 future._setError(e);
348 return;
349 } catch (e, s) {
350 subscription.cancel();
351 future._setError(new AsyncError(e, s));
352 return;
353 }
354 if (foundSmaller) min = value;
298 }); 355 });
299 }, 356 },
300 onError: future._setError, 357 onError: future._setError,
301 onDone: () { 358 onDone: () {
302 future._setValue(min); 359 future._setValue(min);
303 }, 360 },
304 unsubscribeOnError: true 361 unsubscribeOnError: true
305 ); 362 );
306 return future; 363 return future;
307 } 364 }
(...skipping 10 matching lines...) Expand all
318 */ 375 */
319 Future<T> max([int compare(T a, T b)]) { 376 Future<T> max([int compare(T a, T b)]) {
320 if (compare == null) compare = Comparable.compare; 377 if (compare == null) compare = Comparable.compare;
321 _FutureImpl<T> future = new _FutureImpl<T>(); 378 _FutureImpl<T> future = new _FutureImpl<T>();
322 StreamSubscription subscription; 379 StreamSubscription subscription;
323 T max = null; 380 T max = null;
324 subscription = this.listen( 381 subscription = this.listen(
325 (T value) { 382 (T value) {
326 max = value; 383 max = value;
327 subscription.onData((T value) { 384 subscription.onData((T value) {
328 if (compare(max, value) < 0) max = value; 385 bool foundGreater;
386 try {
387 foundGreater = (compare(min, value) < 0);
388 } on AsyncError catch (e) {
389 subscription.cancel();
390 future._setError(e);
391 return;
392 } catch (e, s) {
393 subscription.cancel();
394 future._setError(new AsyncError(e, s));
395 return;
396 }
397 if (foundGreater) min = value;
329 }); 398 });
330 }, 399 },
331 onError: future._setError, 400 onError: future._setError,
332 onDone: () { 401 onDone: () {
333 future._setValue(max); 402 future._setValue(max);
334 }, 403 },
335 unsubscribeOnError: true 404 unsubscribeOnError: true
336 ); 405 );
337 return future; 406 return future;
338 } 407 }
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 * error. 611 * error.
543 */ 612 */
544 Future<T> firstMatching(bool test(T value), {T defaultValue()}) { 613 Future<T> firstMatching(bool test(T value), {T defaultValue()}) {
545 _FutureImpl<T> future = new _FutureImpl<T>(); 614 _FutureImpl<T> future = new _FutureImpl<T>();
546 StreamSubscription subscription; 615 StreamSubscription subscription;
547 subscription = this.listen( 616 subscription = this.listen(
548 (T value) { 617 (T value) {
549 bool matches; 618 bool matches;
550 try { 619 try {
551 matches = (true == test(value)); 620 matches = (true == test(value));
621 } on AsyncError catch (e) {
622 subscription.cancel();
623 future._setError(e);
624 return;
552 } catch (e, s) { 625 } catch (e, s) {
626 subscription.cancel();
553 future._setError(new AsyncError(e, s)); 627 future._setError(new AsyncError(e, s));
554 subscription.cancel();
555 return; 628 return;
556 } 629 }
557 if (matches) { 630 if (matches) {
631 subscription.cancel();
558 future._setValue(value); 632 future._setValue(value);
559 subscription.cancel();
560 } 633 }
561 }, 634 },
562 onError: future._setError, 635 onError: future._setError,
563 onDone: () { 636 onDone: () {
564 if (defaultValue != null) { 637 if (defaultValue != null) {
565 T value; 638 T value;
566 try { 639 try {
567 value = defaultValue(); 640 value = defaultValue();
641 } on AsyncError catch (e) {
642 future._setError(e);
643 return;
568 } catch (e, s) { 644 } catch (e, s) {
569 future._setError(new AsyncError(e, s)); 645 future._setError(new AsyncError(e, s));
570 return; 646 return;
571 } 647 }
572 future._setValue(value); 648 future._setValue(value);
573 return; 649 return;
574 } 650 }
575 future._setError( 651 future._setError(
576 new AsyncError(new StateError("firstMatch ended without match"))); 652 new AsyncError(new StateError("firstMatch ended without match")));
577 }, 653 },
(...skipping 11 matching lines...) Expand all
589 Future<T> lastMatching(bool test(T value), {T defaultValue()}) { 665 Future<T> lastMatching(bool test(T value), {T defaultValue()}) {
590 _FutureImpl<T> future = new _FutureImpl<T>(); 666 _FutureImpl<T> future = new _FutureImpl<T>();
591 T result = null; 667 T result = null;
592 bool foundResult = false; 668 bool foundResult = false;
593 StreamSubscription subscription; 669 StreamSubscription subscription;
594 subscription = this.listen( 670 subscription = this.listen(
595 (T value) { 671 (T value) {
596 bool matches; 672 bool matches;
597 try { 673 try {
598 matches = (true == test(value)); 674 matches = (true == test(value));
675 } on AsyncError catch (e) {
676 subscription.cancel();
677 future._setError(e);
678 return;
599 } catch (e, s) { 679 } catch (e, s) {
680 subscription.cancel();
600 future._setError(new AsyncError(e, s)); 681 future._setError(new AsyncError(e, s));
601 subscription.cancel();
602 return; 682 return;
603 } 683 }
604 if (matches) { 684 if (matches) {
605 foundResult = true; 685 foundResult = true;
606 result = value; 686 result = value;
607 } 687 }
608 }, 688 },
609 onError: future._setError, 689 onError: future._setError,
610 onDone: () { 690 onDone: () {
611 if (foundResult) { 691 if (foundResult) {
612 future._setValue(result); 692 future._setValue(result);
613 return; 693 return;
614 } 694 }
615 if (defaultValue != null) { 695 if (defaultValue != null) {
616 T value; 696 T value;
617 try { 697 try {
618 value = defaultValue(); 698 value = defaultValue();
699 } on AsyncError catch (e) {
700 future._setError(e);
701 return;
619 } catch (e, s) { 702 } catch (e, s) {
620 future._setError(new AsyncError(e, s)); 703 future._setError(new AsyncError(e, s));
621 return; 704 return;
622 } 705 }
623 future._setValue(value); 706 future._setValue(value);
624 return; 707 return;
625 } 708 }
626 future._setError( 709 future._setError(
627 new AsyncError(new StateError("lastMatch ended without match"))); 710 new AsyncError(new StateError("lastMatch ended without match")));
628 }, 711 },
(...skipping 10 matching lines...) Expand all
639 Future<T> singleMatching(bool test(T value)) { 722 Future<T> singleMatching(bool test(T value)) {
640 _FutureImpl<T> future = new _FutureImpl<T>(); 723 _FutureImpl<T> future = new _FutureImpl<T>();
641 T result = null; 724 T result = null;
642 bool foundResult = false; 725 bool foundResult = false;
643 StreamSubscription subscription; 726 StreamSubscription subscription;
644 subscription = this.listen( 727 subscription = this.listen(
645 (T value) { 728 (T value) {
646 bool matches; 729 bool matches;
647 try { 730 try {
648 matches = (true == test(value)); 731 matches = (true == test(value));
732 } on AsyncError catch (e) {
733 subscription.cancel();
734 future._setError(e);
735 return;
649 } catch (e, s) { 736 } catch (e, s) {
737 subscription.cancel();
650 future._setError(new AsyncError(e, s)); 738 future._setError(new AsyncError(e, s));
651 subscription.cancel();
652 return; 739 return;
653 } 740 }
654 if (matches) { 741 if (matches) {
655 if (foundResult) { 742 if (foundResult) {
743 subscription.cancel();
656 future._setError(new AsyncError( 744 future._setError(new AsyncError(
657 new StateError('Multiple matches for "single"'))); 745 new StateError('Multiple matches for "single"')));
658 subscription.cancel();
659 return; 746 return;
660 } 747 }
661 foundResult = true; 748 foundResult = true;
662 result = value; 749 result = value;
663 } 750 }
664 }, 751 },
665 onError: future._setError, 752 onError: future._setError,
666 onDone: () { 753 onDone: () {
667 if (foundResult) { 754 if (foundResult) {
668 future._setValue(result); 755 future._setValue(result);
669 return; 756 return;
670 } 757 }
671 future._setError( 758 future._setError(
672 new AsyncError(new StateError("single ended without match"))); 759 new AsyncError(new StateError("single ended without match")));
673 }, 760 },
674 unsubscribeOnError: true); 761 unsubscribeOnError: true);
675 return future; 762 return future;
676 } 763 }
677 764
678 /** 765 /**
679 * Returns the value of the [index]th data event of this stream. 766 * Returns the value of the [index]th data event of this stream.
680 * 767 *
681 * If an error event occurs, the future will end with this error. 768 * If an error event occurs, the future will end with this error.
682 * 769 *
683 * If this stream provides fewer than [index] elements before closing, 770 * If this stream provides fewer than [index] elements before closing,
684 * an error is reported. 771 * an error is reported.
685 */ 772 */
686 Future<T> elementAt(int index) { 773 Future<T> elementAt(int index) {
774 if (0 > index) throw new ArgumentError(index);
floitsch 2013/01/11 13:23:33 No. If you don't want to check for int, don't chec
Lasse Reichstein Nielsen 2013/01/14 08:33:30 Done.
687 _FutureImpl<T> future = new _FutureImpl(); 775 _FutureImpl<T> future = new _FutureImpl();
688 StreamSubscription subscription; 776 StreamSubscription subscription;
689 subscription = this.listen( 777 subscription = this.listen(
690 (T value) { 778 (T value) {
691 if (index == 0) { 779 if (index == 0) {
692 future._setValue(value); 780 future._setValue(value);
693 subscription.cancel(); 781 subscription.cancel();
694 return; 782 return;
695 } 783 }
696 index -= 1; 784 index -= 1;
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
852 sink.signalError(error); 940 sink.signalError(error);
853 } 941 }
854 942
855 /** 943 /**
856 * Handle an incoming done event. 944 * Handle an incoming done event.
857 */ 945 */
858 void handleDone(StreamSink<T> sink) { 946 void handleDone(StreamSink<T> sink) {
859 sink.close(); 947 sink.close();
860 } 948 }
861 } 949 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/async/stream_controller.dart » ('j') | sdk/lib/async/stream_pipe.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698