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

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

Issue 295913003: Make Stream.where, etc., be documented as inheriting broadcast state. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Change asBroadcastStream to always only listen once to its source. Created 6 years, 7 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_transformers.dart » ('j') | tests/co19/co19-co19.status » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 * itself when the listener is unsubscribed, even if the stream wasn't done. 42 * itself when the listener is unsubscribed, even if the stream wasn't done.
43 * 43 *
44 * Single-subscription streams are generally used for streaming parts of 44 * Single-subscription streams are generally used for streaming parts of
45 * contiguous data like file I/O. 45 * contiguous data like file I/O.
46 * 46 *
47 * A broadcast stream allows any number of listeners, and it fires 47 * A broadcast stream allows any number of listeners, and it fires
48 * its events when they are ready, whether there are listeners or not. 48 * its events when they are ready, whether there are listeners or not.
49 * 49 *
50 * Broadcast streams are used for independent events/observers. 50 * Broadcast streams are used for independent events/observers.
51 * 51 *
52 * Stream transformations, such as [where] and [skip], always return 52 * Stream transformations, such as [where] and [skip],
53 * non-broadcast streams. If several listeners want to listen to the returned 53 * return the same type of stream as the one the method was called on,
54 * unless otherwise noted.
55 *
56 * If several listeners want to listen to the returned
54 * stream, use [asBroadcastStream] to create a broadcast stream on top of the 57 * stream, use [asBroadcastStream] to create a broadcast stream on top of the
55 * non-broadcast stream. 58 * non-broadcast stream.
56 * 59 *
57 * The default implementation of [isBroadcast] returns false. 60 * The default implementation of [isBroadcast] returns false.
58 * A broadcast stream inheriting from [Stream] must override [isBroadcast] 61 * A broadcast stream inheriting from [Stream] must override [isBroadcast]
59 * to return [:true:]. 62 * to return [:true:].
60 */ 63 */
61 abstract class Stream<T> { 64 abstract class Stream<T> {
62 Stream(); 65 Stream();
63 66
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 } 199 }
197 200
198 /** 201 /**
199 * Reports whether this stream is a broadcast stream. 202 * Reports whether this stream is a broadcast stream.
200 */ 203 */
201 bool get isBroadcast => false; 204 bool get isBroadcast => false;
202 205
203 /** 206 /**
204 * Returns a multi-subscription stream that produces the same events as this. 207 * Returns a multi-subscription stream that produces the same events as this.
205 * 208 *
206 * If this stream is already a broadcast stream, it is returned unmodified. 209 * The returned stream will subscribe to this stream when its first
207 *
208 * If this stream is single-subscription, return a new stream that allows
209 * multiple subscribers. It will subscribe to this stream when its first
210 * subscriber is added, and will stay subscribed until this stream ends, 210 * subscriber is added, and will stay subscribed until this stream ends,
211 * or a callback cancels the subscription. 211 * or a callback cancels the subscription.
212 * 212 *
213 * If [onListen] is provided, it is called with a subscription-like object 213 * If [onListen] is provided, it is called with a subscription-like object
214 * that represents the underlying subscription to this stream. It is 214 * that represents the underlying subscription to this stream. It is
215 * possible to pause, resume or cancel the subscription during the call 215 * possible to pause, resume or cancel the subscription during the call
216 * to [onListen]. It is not possible to change the event handlers, including 216 * to [onListen]. It is not possible to change the event handlers, including
217 * using [StreamSubscription.asFuture]. 217 * using [StreamSubscription.asFuture].
218 * 218 *
219 * If [onCancel] is provided, it is called in a similar way to [onListen] 219 * If [onCancel] is provided, it is called in a similar way to [onListen]
220 * when the returned stream stops having listener. If it later gets 220 * when the returned stream stops having listener. If it later gets
221 * a new listener, the [onListen] function is called again. 221 * a new listener, the [onListen] function is called again.
222 * 222 *
223 * Use the callbacks, for example, for pausing the underlying subscription 223 * Use the callbacks, for example, for pausing the underlying subscription
224 * while having no subscribers to prevent losing events, or canceling the 224 * while having no subscribers to prevent losing events, or canceling the
225 * subscription when there are no listeners. 225 * subscription when there are no listeners.
226 */ 226 */
227 Stream<T> asBroadcastStream({ 227 Stream<T> asBroadcastStream({
228 void onListen(StreamSubscription<T> subscription), 228 void onListen(StreamSubscription<T> subscription),
229 void onCancel(StreamSubscription<T> subscription) }) { 229 void onCancel(StreamSubscription<T> subscription) }) {
230 if (isBroadcast) return this;
231 return new _AsBroadcastStream<T>(this, onListen, onCancel); 230 return new _AsBroadcastStream<T>(this, onListen, onCancel);
232 } 231 }
233 232
234 /** 233 /**
235 * Adds a subscription to this stream. 234 * Adds a subscription to this stream.
236 * 235 *
237 * On each data event from this stream, the subscriber's [onData] handler 236 * On each data event from this stream, the subscriber's [onData] handler
238 * is called. If [onData] is null, nothing happens. 237 * is called. If [onData] is null, nothing happens.
239 * 238 *
240 * On errors from this stream, the [onError] handler is given a 239 * On errors from this stream, the [onError] handler is given a
(...skipping 14 matching lines...) Expand all
255 { Function onError, 254 { Function onError,
256 void onDone(), 255 void onDone(),
257 bool cancelOnError}); 256 bool cancelOnError});
258 257
259 /** 258 /**
260 * Creates a new stream from this stream that discards some data events. 259 * Creates a new stream from this stream that discards some data events.
261 * 260 *
262 * The new stream sends the same error and done events as this stream, 261 * The new stream sends the same error and done events as this stream,
263 * but it only sends the data events that satisfy the [test]. 262 * but it only sends the data events that satisfy the [test].
264 * 263 *
265 * The returned stream is not a broadcast stream, even if this stream is. 264 * The returned stream is a broadcast stream if this stream is.
266 */ 265 */
267 Stream<T> where(bool test(T event)) { 266 Stream<T> where(bool test(T event)) {
268 return new _WhereStream<T>(this, test); 267 return new _WhereStream<T>(this, test);
269 } 268 }
270 269
271 /** 270 /**
272 * Creates a new stream that converts each element of this stream 271 * Creates a new stream that converts each element of this stream
273 * to a new value using the [convert] function. 272 * to a new value using the [convert] function.
274 * 273 *
275 * The returned stream is not a broadcast stream, even if this stream is. 274 * The returned stream is a broadcast stream if this stream is.
276 */ 275 */
277 Stream map(convert(T event)) { 276 Stream map(convert(T event)) {
278 return new _MapStream<T, dynamic>(this, convert); 277 return new _MapStream<T, dynamic>(this, convert);
279 } 278 }
280 279
281 /** 280 /**
282 * Creates a new stream with each data event of this stream asynchronously 281 * Creates a new stream with each data event of this stream asynchronously
283 * mapped to a new event. 282 * mapped to a new event.
284 * 283 *
285 * This acts like [map], except that [convert] may return a [Future], 284 * This acts like [map], except that [convert] may return a [Future],
286 * and in that case, the stream waits for that future to complete before 285 * and in that case, the stream waits for that future to complete before
287 * continuing with its result. 286 * continuing with its result.
287 *
288 * The returned stream is not a broadcast stream.
nweiz 2014/05/20 21:15:54 Clarify that despite this being a single-subscript
Lasse Reichstein Nielsen 2014/05/21 06:16:53 Technically, streams never buffer anything. Contro
288 */ 289 */
289 Stream asyncMap(convert(T event)) { 290 Stream asyncMap(convert(T event)) {
290 StreamController controller; 291 StreamController controller;
291 StreamSubscription subscription; 292 StreamSubscription subscription;
292 controller = new StreamController( 293 controller = new StreamController(
293 onListen: () { 294 onListen: () {
294 var add = controller.add; 295 var add = controller.add;
295 var addError = controller.addError; 296 var addError = controller.addError;
296 subscription = this.listen( 297 subscription = this.listen(
297 (T event) { 298 (T event) {
(...skipping 27 matching lines...) Expand all
325 /** 326 /**
326 * Creates a new stream with the events of a stream per original event. 327 * Creates a new stream with the events of a stream per original event.
327 * 328 *
328 * This acts like [expand], except that [convert] returns a [Stream] 329 * This acts like [expand], except that [convert] returns a [Stream]
329 * instead of an [Iterable]. 330 * instead of an [Iterable].
330 * The events of the returned stream becomes the events of the returned 331 * The events of the returned stream becomes the events of the returned
331 * stream, in the order they are produced. 332 * stream, in the order they are produced.
332 * 333 *
333 * If [convert] returns `null`, no value is put on the output stream, 334 * If [convert] returns `null`, no value is put on the output stream,
334 * just as if it returned an empty stream. 335 * just as if it returned an empty stream.
336 *
337 * The returned stream is a not a broadcast stream.
335 */ 338 */
336 Stream asyncExpand(Stream convert(T event)) { 339 Stream asyncExpand(Stream convert(T event)) {
337 StreamController controller; 340 StreamController controller;
338 StreamSubscription subscription; 341 StreamSubscription subscription;
339 controller = new StreamController( 342 controller = new StreamController(
340 onListen: () { 343 onListen: () {
341 subscription = this.listen( 344 subscription = this.listen(
342 (T event) { 345 (T event) {
343 Stream newStream; 346 Stream newStream;
344 try { 347 try {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 * returns true. If [test] is omitted, every error is considered matching. 384 * returns true. If [test] is omitted, every error is considered matching.
382 * 385 *
383 * If the error is intercepted, the [handle] function can decide what to do 386 * If the error is intercepted, the [handle] function can decide what to do
384 * with it. It can throw if it wants to raise a new (or the same) error, 387 * with it. It can throw if it wants to raise a new (or the same) error,
385 * or simply return to make the stream forget the error. 388 * or simply return to make the stream forget the error.
386 * 389 *
387 * If you need to transform an error into a data event, use the more generic 390 * If you need to transform an error into a data event, use the more generic
388 * [Stream.transform] to handle the event by writing a data event to 391 * [Stream.transform] to handle the event by writing a data event to
389 * the output sink 392 * the output sink
390 * 393 *
391 * The returned stream is not a broadcast stream, even if this stream is. 394 * The returned stream is a broadcast stream if this stream is.
392 */ 395 */
393 Stream<T> handleError(Function onError, { bool test(error) }) { 396 Stream<T> handleError(Function onError, { bool test(error) }) {
394 return new _HandleErrorStream<T>(this, onError, test); 397 return new _HandleErrorStream<T>(this, onError, test);
395 } 398 }
396 399
397 /** 400 /**
398 * Creates a new stream from this stream that converts each element 401 * Creates a new stream from this stream that converts each element
399 * into zero or more events. 402 * into zero or more events.
400 * 403 *
401 * Each incoming event is converted to an [Iterable] of new events, 404 * Each incoming event is converted to an [Iterable] of new events,
402 * and each of these new events are then sent by the returned stream 405 * and each of these new events are then sent by the returned stream
403 * in order. 406 * in order.
404 * 407 *
405 * The returned stream is not a broadcast stream, even if this stream is. 408 * The returned stream is a broadcast stream if this stream is.
406 */ 409 */
407 Stream expand(Iterable convert(T value)) { 410 Stream expand(Iterable convert(T value)) {
408 return new _ExpandStream<T, dynamic>(this, convert); 411 return new _ExpandStream<T, dynamic>(this, convert);
409 } 412 }
410 413
411 /** 414 /**
412 * Binds this stream as the input of the provided [StreamConsumer]. 415 * Binds this stream as the input of the provided [StreamConsumer].
413 */ 416 */
414 Future pipe(StreamConsumer<T> streamConsumer) { 417 Future pipe(StreamConsumer<T> streamConsumer) {
415 return streamConsumer.addStream(this).then((_) => streamConsumer.close()); 418 return streamConsumer.addStream(this).then((_) => streamConsumer.close());
416 } 419 }
417 420
418 /** 421 /**
419 * Chains this stream as the input of the provided [StreamTransformer]. 422 * Chains this stream as the input of the provided [StreamTransformer].
420 * 423 *
421 * Returns the result of [:streamTransformer.bind:] itself. 424 * Returns the result of [:streamTransformer.bind:] itself.
425 *
426 * The `streamTransformer` can decide whether it wants to return a
427 * broadcast stream or not.
422 */ 428 */
423 Stream transform(StreamTransformer<T, dynamic> streamTransformer) { 429 Stream transform(StreamTransformer<T, dynamic> streamTransformer) {
424 return streamTransformer.bind(this); 430 return streamTransformer.bind(this);
425 } 431 }
426 432
427 /** 433 /**
428 * Reduces a sequence of values by repeatedly applying [combine]. 434 * Reduces a sequence of values by repeatedly applying [combine].
429 */ 435 */
430 Future<T> reduce(T combine(T previous, T element)) { 436 Future<T> reduce(T combine(T previous, T element)) {
431 _Future<T> result = new _Future<T>(); 437 _Future<T> result = new _Future<T>();
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 * If this stream produces fewer than [count] values before it's done, 737 * If this stream produces fewer than [count] values before it's done,
732 * so will the returned stream. 738 * so will the returned stream.
733 * 739 *
734 * Stops listening to the stream after the first [n] elements have been 740 * Stops listening to the stream after the first [n] elements have been
735 * received. 741 * received.
736 * 742 *
737 * Internally the method cancels its subscription after these elements. This 743 * Internally the method cancels its subscription after these elements. This
738 * means that single-subscription (non-broadcast) streams are closed and 744 * means that single-subscription (non-broadcast) streams are closed and
739 * cannot be reused after a call to this method. 745 * cannot be reused after a call to this method.
740 * 746 *
741 * The returned stream is not a broadcast stream, even if this stream is. 747 * The returned stream is a broadcast stream if this stream is.
742 */ 748 */
743 Stream<T> take(int count) { 749 Stream<T> take(int count) {
744 return new _TakeStream(this, count); 750 return new _TakeStream(this, count);
745 } 751 }
746 752
747 /** 753 /**
748 * Forwards data events while [test] is successful. 754 * Forwards data events while [test] is successful.
749 * 755 *
750 * The returned stream provides the same events as this stream as long 756 * The returned stream provides the same events as this stream as long
751 * as [test] returns [:true:] for the event data. The stream is done 757 * as [test] returns [:true:] for the event data. The stream is done
752 * when either this stream is done, or when this stream first provides 758 * when either this stream is done, or when this stream first provides
753 * a value that [test] doesn't accept. 759 * a value that [test] doesn't accept.
754 * 760 *
755 * Stops listening to the stream after the accepted elements. 761 * Stops listening to the stream after the accepted elements.
756 * 762 *
757 * Internally the method cancels its subscription after these elements. This 763 * Internally the method cancels its subscription after these elements. This
758 * means that single-subscription (non-broadcast) streams are closed and 764 * means that single-subscription (non-broadcast) streams are closed and
759 * cannot be reused after a call to this method. 765 * cannot be reused after a call to this method.
760 * 766 *
761 * The returned stream is not a broadcast stream, even if this stream is. 767 * The returned stream is a broadcast stream if this stream is.
762 */ 768 */
763 Stream<T> takeWhile(bool test(T element)) { 769 Stream<T> takeWhile(bool test(T element)) {
764 return new _TakeWhileStream(this, test); 770 return new _TakeWhileStream(this, test);
765 } 771 }
766 772
767 /** 773 /**
768 * Skips the first [count] data events from this stream. 774 * Skips the first [count] data events from this stream.
769 * 775 *
770 * The returned stream is not a broadcast stream, even if this stream is. 776 * The returned stream is a broadcast stream if this stream is.
771 */ 777 */
772 Stream<T> skip(int count) { 778 Stream<T> skip(int count) {
773 return new _SkipStream(this, count); 779 return new _SkipStream(this, count);
774 } 780 }
775 781
776 /** 782 /**
777 * Skip data events from this stream while they are matched by [test]. 783 * Skip data events from this stream while they are matched by [test].
778 * 784 *
779 * Error and done events are provided by the returned stream unmodified. 785 * Error and done events are provided by the returned stream unmodified.
780 * 786 *
781 * Starting with the first data event where [test] returns false for the 787 * Starting with the first data event where [test] returns false for the
782 * event data, the returned stream will have the same events as this stream. 788 * event data, the returned stream will have the same events as this stream.
783 * 789 *
784 * The returned stream is not a broadcast stream, even if this stream is. 790 * The returned stream is a broadcast stream if this stream is.
785 */ 791 */
786 Stream<T> skipWhile(bool test(T element)) { 792 Stream<T> skipWhile(bool test(T element)) {
787 return new _SkipWhileStream(this, test); 793 return new _SkipWhileStream(this, test);
788 } 794 }
789 795
790 /** 796 /**
791 * Skips data events if they are equal to the previous data event. 797 * Skips data events if they are equal to the previous data event.
792 * 798 *
793 * The returned stream provides the same events as this stream, except 799 * The returned stream provides the same events as this stream, except
794 * that it never provides two consequtive data events that are equal. 800 * that it never provides two consequtive data events that are equal.
795 * 801 *
796 * Equality is determined by the provided [equals] method. If that is 802 * Equality is determined by the provided [equals] method. If that is
797 * omitted, the '==' operator on the last provided data element is used. 803 * omitted, the '==' operator on the last provided data element is used.
798 * 804 *
799 * The returned stream is not a broadcast stream, even if this stream is. 805 * The returned stream is a broadcast stream if this stream is.
800 */ 806 */
801 Stream<T> distinct([bool equals(T previous, T next)]) { 807 Stream<T> distinct([bool equals(T previous, T next)]) {
802 return new _DistinctStream(this, equals); 808 return new _DistinctStream(this, equals);
803 } 809 }
804 810
805 /** 811 /**
806 * Returns the first element of the stream. 812 * Returns the first element of the stream.
807 * 813 *
808 * Stops listening to the stream after the first element has been received. 814 * Stops listening to the stream after the first element has been received.
809 * 815 *
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 * The countdown is reset every time an event is forwarded from this stream, 1087 * The countdown is reset every time an event is forwarded from this stream,
1082 * or when the stream is paused and resumed. 1088 * or when the stream is paused and resumed.
1083 * 1089 *
1084 * The [onTimeout] function is called with one argument: an 1090 * The [onTimeout] function is called with one argument: an
1085 * [EventSink] that allows putting events into the returned stream. 1091 * [EventSink] that allows putting events into the returned stream.
1086 * This `EventSink` is only valid during the call to `onTimeout`. 1092 * This `EventSink` is only valid during the call to `onTimeout`.
1087 * 1093 *
1088 * If `onTimeout` is omitted, a timeout will just put a [TimeoutException] 1094 * If `onTimeout` is omitted, a timeout will just put a [TimeoutException]
1089 * into the error channel of the returned stream. 1095 * into the error channel of the returned stream.
1090 * 1096 *
1091 * The returned stream is not a broadcast stream, even if this stream is. 1097 * The returned stream is a broadcast stream if this stream is.
1092 */ 1098 */
1093 Stream timeout(Duration timeLimit, {void onTimeout(EventSink sink)}) { 1099 Stream timeout(Duration timeLimit, {void onTimeout(EventSink sink)}) {
1100 StreamController controller;
1101 // The following variables are set on listen.
1094 StreamSubscription<T> subscription; 1102 StreamSubscription<T> subscription;
1095 _StreamController controller;
1096 // The following variables are set on listen.
1097 Timer timer; 1103 Timer timer;
1098 Zone zone; 1104 Zone zone;
1099 Function timeout; 1105 Function timeout;
1100 1106
1101 void onData(T event) { 1107 void onData(T event) {
1102 timer.cancel(); 1108 timer.cancel();
1103 controller.add(event); 1109 controller.add(event);
1104 timer = zone.createTimer(timeLimit, timeout); 1110 timer = zone.createTimer(timeLimit, timeout);
1105 } 1111 }
1106 void onError(error, StackTrace stackTrace) { 1112 void onError(error, StackTrace stackTrace) {
1107 timer.cancel(); 1113 timer.cancel();
1108 controller.addError(error, stackTrace); 1114 controller.addError(error, stackTrace);
1109 timer = zone.createTimer(timeLimit, timeout); 1115 timer = zone.createTimer(timeLimit, timeout);
1110 } 1116 }
1111 void onDone() { 1117 void onDone() {
1112 timer.cancel(); 1118 timer.cancel();
1113 controller.close(); 1119 controller.close();
1114 } 1120 }
1115 controller = new _SyncStreamController( 1121 void onListen() {
1116 () { 1122 // This is the onListen callback for of controller.
1117 // This is the onListen callback for of controller. 1123 // It runs in the same zone that the subscription was created in.
1118 // It runs in the same zone that the subscription was created in. 1124 // Use that zone for creating timers and running the onTimeout
1119 // Use that zone for creating timers and running the onTimeout 1125 // callback.
1120 // callback. 1126 zone = Zone.current;
1121 zone = Zone.current; 1127 if (onTimeout == null) {
1122 if (onTimeout == null) { 1128 timeout = () {
1123 timeout = () { 1129 controller.addError(new TimeoutException("No stream event",
1124 controller.addError(new TimeoutException("No stream event", 1130 timeLimit));
1125 timeLimit)); 1131 };
1126 }; 1132 } else {
1127 } else { 1133 onTimeout = zone.registerUnaryCallback(onTimeout);
1128 onTimeout = zone.registerUnaryCallback(onTimeout); 1134 _ControllerEventSinkWrapper wrapper =
1129 _ControllerEventSinkWrapper wrapper = 1135 new _ControllerEventSinkWrapper(null);
1130 new _ControllerEventSinkWrapper(null); 1136 timeout = () {
1131 timeout = () { 1137 wrapper._sink = controller; // Only valid during call.
1132 wrapper._sink = controller; // Only valid during call. 1138 zone.runUnaryGuarded(onTimeout, wrapper);
1133 zone.runUnaryGuarded(onTimeout, wrapper); 1139 wrapper._sink = null;
1134 wrapper._sink = null; 1140 };
1135 }; 1141 }
1136 }
1137 1142
1138 subscription = this.listen(onData, onError: onError, onDone: onDone); 1143 subscription = this.listen(onData, onError: onError, onDone: onDone);
1139 timer = zone.createTimer(timeLimit, timeout); 1144 timer = zone.createTimer(timeLimit, timeout);
1140 }, 1145 }
1141 () { 1146 Future onCancel() {
1142 timer.cancel(); 1147 timer.cancel();
1143 subscription.pause(); 1148 Future result = subscription.cancel();
1144 }, 1149 subscription = null;
1145 () { 1150 return result;
1146 subscription.resume(); 1151 }
1147 timer = zone.createTimer(timeLimit, timeout); 1152 controller = isBroadcast
1148 }, 1153 ? new _SyncBroadcastStreamController(onListen, onCancel)
1149 () { 1154 : new _SyncStreamController(
1150 timer.cancel(); 1155 onListen,
1151 Future result = subscription.cancel(); 1156 () {
1152 subscription = null; 1157 // Don't null the timer, onCancel may call cancel again.
1153 return result; 1158 timer.cancel();
1154 }); 1159 subscription.pause();
1160 },
1161 () {
1162 subscription.resume();
1163 timer = zone.createTimer(timeLimit, timeout);
1164 },
1165 onCancel);
1155 return controller.stream; 1166 return controller.stream;
1156 } 1167 }
1157 } 1168 }
1158 1169
1159 /** 1170 /**
1160 * A control object for the subscription on a [Stream]. 1171 * A control object for the subscription on a [Stream].
1161 * 1172 *
1162 * When you subscribe on a [Stream] using [Stream.listen], 1173 * When you subscribe on a [Stream] using [Stream.listen],
1163 * a [StreamSubscription] object is returned. This object 1174 * a [StreamSubscription] object is returned. This object
1164 * is used to later unsubscribe again, or to temporarily pause 1175 * is used to later unsubscribe again, or to temporarily pause
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
1489 class _ControllerEventSinkWrapper<T> implements EventSink<T> { 1500 class _ControllerEventSinkWrapper<T> implements EventSink<T> {
1490 EventSink _sink; 1501 EventSink _sink;
1491 _ControllerEventSinkWrapper(this._sink); 1502 _ControllerEventSinkWrapper(this._sink);
1492 1503
1493 void add(T data) { _sink.add(data); } 1504 void add(T data) { _sink.add(data); }
1494 void addError(error, [StackTrace stackTrace]) { 1505 void addError(error, [StackTrace stackTrace]) {
1495 _sink.addError(error, stackTrace); 1506 _sink.addError(error, stackTrace);
1496 } 1507 }
1497 void close() { _sink.close(); } 1508 void close() { _sink.close(); }
1498 } 1509 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/async/stream_transformers.dart » ('j') | tests/co19/co19-co19.status » ('J')

Powered by Google App Engine
This is Rietveld 408576698