OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 controller._closeUnchecked(); | 106 controller._closeUnchecked(); |
107 }, | 107 }, |
108 onError: (error, stackTrace) { | 108 onError: (error, stackTrace) { |
109 controller._addError(error, stackTrace); | 109 controller._addError(error, stackTrace); |
110 controller._closeUnchecked(); | 110 controller._closeUnchecked(); |
111 }); | 111 }); |
112 return controller.stream; | 112 return controller.stream; |
113 } | 113 } |
114 | 114 |
115 /** | 115 /** |
| 116 * Create a stream from a group of futures. |
| 117 * |
| 118 * The stream reports the results of the futures on the stream in the order |
| 119 * in which the futures complete. |
| 120 * |
| 121 * If some futures have completed before calling `Stream.fromFutures`, |
| 122 * their result will be output on the created stream in some unspecified |
| 123 * order. |
| 124 * |
| 125 * When all futures have completed, the stream is closed. |
| 126 * |
| 127 * If no future is passed, the stream closes as soon as possible. |
| 128 */ |
| 129 factory Stream.fromFutures(Iterable<Future<T>> futures) { |
| 130 var controller = new StreamController<T>(sync: true); |
| 131 int count = 0; |
| 132 var onValue = (value) { |
| 133 if (!controller.isClosed) { |
| 134 controller._add(value); |
| 135 if (--count == 0) controller._closeUnchecked(); |
| 136 } |
| 137 }; |
| 138 var onError = (error, stack) { |
| 139 if (!controller.isClosed) { |
| 140 controller._addError(error, stack); |
| 141 if (--count == 0) controller._closeUnchecked(); |
| 142 } |
| 143 }; |
| 144 // The futures are already running, so start listening to them immediately |
| 145 // (instead of waiting for the stream to be listened on). |
| 146 // If we wait, we might not catch errors in the futures in time. |
| 147 for (var future in futures) { |
| 148 count++; |
| 149 future.then(onValue, onError: onError); |
| 150 } |
| 151 // Use schedule microtask since controller is sync. |
| 152 if (count == 0) scheduleMicrotask(controller.close); |
| 153 return controller.stream; |
| 154 } |
| 155 |
| 156 /** |
116 * Creates a single-subscription stream that gets its data from [data]. | 157 * Creates a single-subscription stream that gets its data from [data]. |
117 * | 158 * |
118 * The iterable is iterated when the stream receives a listener, and stops | 159 * The iterable is iterated when the stream receives a listener, and stops |
119 * iterating if the listener cancels the subscription. | 160 * iterating if the listener cancels the subscription. |
120 * | 161 * |
121 * If iterating [data] throws an error, the stream ends immediately with | 162 * If iterating [data] throws an error, the stream ends immediately with |
122 * that error. No done event will be sent (iteration is not complete), but no | 163 * that error. No done event will be sent (iteration is not complete), but no |
123 * further data events will be generated either, since iteration cannot | 164 * further data events will be generated either, since iteration cannot |
124 * continue. | 165 * continue. |
125 */ | 166 */ |
(...skipping 1625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1751 class _ControllerEventSinkWrapper<T> implements EventSink<T> { | 1792 class _ControllerEventSinkWrapper<T> implements EventSink<T> { |
1752 EventSink _sink; | 1793 EventSink _sink; |
1753 _ControllerEventSinkWrapper(this._sink); | 1794 _ControllerEventSinkWrapper(this._sink); |
1754 | 1795 |
1755 void add(T data) { _sink.add(data); } | 1796 void add(T data) { _sink.add(data); } |
1756 void addError(error, [StackTrace stackTrace]) { | 1797 void addError(error, [StackTrace stackTrace]) { |
1757 _sink.addError(error, stackTrace); | 1798 _sink.addError(error, stackTrace); |
1758 } | 1799 } |
1759 void close() { _sink.close(); } | 1800 void close() { _sink.close(); } |
1760 } | 1801 } |
OLD | NEW |