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 typedef R ZoneCallback<R>(); | 7 typedef R ZoneCallback<R>(); |
8 typedef R ZoneUnaryCallback<R, T>(T arg); | 8 typedef R ZoneUnaryCallback<R, T>(T arg); |
9 typedef R ZoneBinaryCallback<R, T1, T2>(T1 arg1, T2 arg2); | 9 typedef R ZoneBinaryCallback<R, T1, T2>(T1 arg1, T2 arg2); |
10 | 10 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
50 typedef void RunTaskHandler/*<T, A>*/(Zone self, ZoneDelegate parent, Zone zone, | 50 typedef void RunTaskHandler/*<T, A>*/(Zone self, ZoneDelegate parent, Zone zone, |
51 TaskRun/*<T, A>*/ run, Object/*=T*/ task, Object/*=A*/ arg); | 51 TaskRun/*<T, A>*/ run, Object/*=T*/ task, Object/*=A*/ arg); |
52 typedef void ScheduleMicrotaskHandler( | 52 typedef void ScheduleMicrotaskHandler( |
53 Zone self, ZoneDelegate parent, Zone zone, void f()); | 53 Zone self, ZoneDelegate parent, Zone zone, void f()); |
54 typedef void PrintHandler( | 54 typedef void PrintHandler( |
55 Zone self, ZoneDelegate parent, Zone zone, String line); | 55 Zone self, ZoneDelegate parent, Zone zone, String line); |
56 typedef Zone ForkHandler(Zone self, ZoneDelegate parent, Zone zone, | 56 typedef Zone ForkHandler(Zone self, ZoneDelegate parent, Zone zone, |
57 ZoneSpecification specification, | 57 ZoneSpecification specification, |
58 Map zoneValues); | 58 Map zoneValues); |
59 | 59 |
60 // Typedefs for methods, that will be deprecated once tasks are | 60 // Typedefs for methods, that will be deprecated once tasks are |
Lasse Reichstein Nielsen
2016/07/01 11:25:01
remove comma.
This is not a dart-doc, so it doesn
floitsch
2016/07/02 03:11:20
Done.
| |
61 // non-experimental. | 61 // non-experimental. |
62 typedef Timer CreateTimerHandler( | 62 typedef Timer CreateTimerHandler( |
63 Zone self, ZoneDelegate parent, Zone zone, Duration duration, void f()); | 63 Zone self, ZoneDelegate parent, Zone zone, Duration duration, void f()); |
64 typedef Timer CreatePeriodicTimerHandler( | 64 typedef Timer CreatePeriodicTimerHandler( |
65 Zone self, ZoneDelegate parent, Zone zone, | 65 Zone self, ZoneDelegate parent, Zone zone, |
66 Duration period, void f(Timer timer)); | 66 Duration period, void f(Timer timer)); |
67 | 67 |
68 /** Pair of error and stack trace. Returned by [Zone.errorCallback]. */ | 68 /** Pair of error and stack trace. Returned by [Zone.errorCallback]. */ |
69 class AsyncError implements Error { | 69 class AsyncError implements Error { |
70 final Object error; | 70 final Object error; |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
270 final PrintHandler print; | 270 final PrintHandler print; |
271 final ForkHandler fork; | 271 final ForkHandler fork; |
272 | 272 |
273 // TODO(floitsch): deprecate once tasks are non-experimental. | 273 // TODO(floitsch): deprecate once tasks are non-experimental. |
274 final CreateTimerHandler createTimer; | 274 final CreateTimerHandler createTimer; |
275 // TODO(floitsch): deprecate once tasks are non-experimental. | 275 // TODO(floitsch): deprecate once tasks are non-experimental. |
276 final CreatePeriodicTimerHandler createPeriodicTimer; | 276 final CreatePeriodicTimerHandler createPeriodicTimer; |
277 } | 277 } |
278 | 278 |
279 /** | 279 /** |
280 * This class wraps zones for delegation. | 280 * An adapted view of the parent zone. |
281 * | 281 * |
282 * When forwarding to parent zones one can't just invoke the parent zone's | 282 * This class allows the implementation of a zone method to invoke methods on |
283 * exposed functions (like [Zone.run]), but one needs to provide more | 283 * the parent zone while retaining knowledge of the originating zone. |
284 * information (like the zone the `run` was initiated). Zone callbacks thus | 284 * |
285 * receive more information including this [ZoneDelegate] class. When delegating | 285 * Custom zones (created through [Zone.fork] or [runZoned]) can provide |
286 * to the parent zone one should go through the given instance instead of | 286 * implementations of most methods of zones. This is similar to overriding |
287 * directly invoking the parent zone. | 287 * methods on [Zone], except that this mechanism doesn't require subclassing. |
288 * | |
289 * A custom zone function (provided through a [ZoneSpecification]) typically | |
290 * records or wraps its parameters and then delegates the operation to its | |
291 * parent zone using the provided [ZoneDelegate]. | |
292 * | |
293 * While zones have access to their parent zone (through [Zone.parent]) it is | |
294 * recommended to call the methods on the provided parent delegate for two | |
295 * reasons: | |
296 * 1. the delegate methods take an additional `zone` argument which is the | |
297 * zone the action has been initiated in. | |
298 * 2. delegate calls are more efficient, since the implementation knows how | |
299 * to skip zones that would just delegate to their parents. | |
288 */ | 300 */ |
289 abstract class ZoneDelegate { | 301 abstract class ZoneDelegate { |
290 /*=R*/ handleUncaughtError/*<R>*/( | 302 /*=R*/ handleUncaughtError/*<R>*/( |
291 Zone zone, error, StackTrace stackTrace); | 303 Zone zone, error, StackTrace stackTrace); |
292 /*=R*/ run/*<R>*/(Zone zone, /*=R*/ f()); | 304 /*=R*/ run/*<R>*/(Zone zone, /*=R*/ f()); |
293 /*=R*/ runUnary/*<R, T>*/(Zone zone, /*=R*/ f(/*=T*/ arg), /*=T*/ arg); | 305 /*=R*/ runUnary/*<R, T>*/(Zone zone, /*=R*/ f(/*=T*/ arg), /*=T*/ arg); |
294 /*=R*/ runBinary/*<R, T1, T2>*/(Zone zone, | 306 /*=R*/ runBinary/*<R, T1, T2>*/(Zone zone, |
295 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2); | 307 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2); |
296 ZoneCallback/*<R>*/ registerCallback/*<R>*/(Zone zone, /*=R*/ f()); | 308 ZoneCallback/*<R>*/ registerCallback/*<R>*/(Zone zone, /*=R*/ f()); |
297 ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/( | 309 ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/( |
(...skipping 13 matching lines...) Expand all Loading... | |
311 void print(Zone zone, String line); | 323 void print(Zone zone, String line); |
312 Zone fork(Zone zone, ZoneSpecification specification, Map zoneValues); | 324 Zone fork(Zone zone, ZoneSpecification specification, Map zoneValues); |
313 | 325 |
314 // TODO(floitsch): deprecate once tasks are non-experimental. | 326 // TODO(floitsch): deprecate once tasks are non-experimental. |
315 Timer createTimer(Zone zone, Duration duration, void f()); | 327 Timer createTimer(Zone zone, Duration duration, void f()); |
316 // TODO(floitsch): deprecate once tasks are non-experimental. | 328 // TODO(floitsch): deprecate once tasks are non-experimental. |
317 Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)); | 329 Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)); |
318 } | 330 } |
319 | 331 |
320 /** | 332 /** |
321 * A Zone represents the asynchronous version of a dynamic extent. Asynchronous | 333 * A zone represents an environment that remains stable across asynchronous |
322 * callbacks are executed in the zone they have been queued in. For example, | 334 * calls. |
323 * the callback of a `future.then` is executed in the same zone as the one where | 335 * |
324 * the `then` was invoked. | 336 * Asynchronous callbacks are executed in the zone they have been queued in. For |
337 * example, the callback of a `future.then` is executed in the same zone as the | |
338 * one where the `then` was invoked. | |
Lasse Reichstein Nielsen
2016/07/01 11:25:01
Consider moving this paragraph somewhere after "Co
floitsch
2016/07/02 03:11:20
Done. Removed.
| |
339 * | |
340 * Code is always executed in the context of a zone, available as | |
341 * [Zone.current]. The initial `main` function runs in the context of the | |
342 * default zone ([Zone.ROOT]). Code can be run in a different zone using either | |
343 * [runZoned], to create a new zone, or [Zone.run] to run code in the context of | |
344 * an existing zone likely created using [Zone.fork]. | |
345 * | |
346 * Developers can create a new zone that overrides some of the functionality of | |
347 * an existing zone. For example, custom zones can replace of modify the | |
348 * behavior of `print`, timers, microtasks or how uncaught errors are handled. | |
349 * | |
350 * The [Zone] class is not subclassable, but users can provide custom zones by | |
351 * forking an existing zone (usually [Zone.current]) with a [ZoneSpecification]. | |
352 * This is similar to creating a new class that extends the base `Zone` class | |
353 * and that overrides some methods, except without actually creating a new | |
354 * class. Instead the overriding methods are provided as functions that | |
355 * explicitly take the equivalent of their own class, the "super" class and the | |
356 * `this` object as parameters. | |
357 * | |
358 * Asynchronous callbacks always run in the context of the zone where they were | |
359 * scheduled. This is implemented using two steps: | |
Lasse Reichstein Nielsen
2016/07/01 11:25:01
Is this repeating paragraph 2 above? (if so, maybe
floitsch
2016/07/02 03:11:19
Done.
| |
360 * 1. the callback is first registered using one of [registerCallback], | |
361 * [registerUnaryCallback], or [registerBinaryCallback]. This allows the zone | |
362 * to record that a callback exists and potentially modify it (by returning a | |
363 * different callback). The code doing the registration (e.g., `Future.then`) | |
364 * also remembers the current zone so that it can later run the callback in | |
365 * that zone. | |
366 * 2. At a later point the registered callback is run in the remembered zone. | |
367 * | |
368 * This is all handled internally by the platform code and most users don't need | |
369 * to worry about it. However, developers of new asynchronous operations, | |
370 * provided by the underlying system or through native extensions, must follow | |
371 * the protocol to be zone compatible. | |
372 * | |
373 * For convenience, zones provide [bindCallback] (and the corresponding | |
374 * [bindUnaryCallback] or [bindBinaryCallback]) to make it easier to respect the | |
375 * zone contract: these functions first invoke the corresponding `register` | |
376 * functions and then wrap the returned function so that it runs in the current | |
377 * zone when it is later asynchronously invoked. | |
325 */ | 378 */ |
326 abstract class Zone { | 379 abstract class Zone { |
327 // Private constructor so that it is not possible instantiate a Zone class. | 380 // Private constructor so that it is not possible instantiate a Zone class. |
328 Zone._(); | 381 Zone._(); |
329 | 382 |
330 /** The root zone that is implicitly created. */ | 383 /** |
384 * The root zone. | |
385 * | |
386 * All isolate entry functions (`main` or spawned functions) start running in | |
387 * the root zone. Without any custom zone the whole program always runs in the | |
Lasse Reichstein Nielsen
2016/07/01 11:25:01
Without any custom zone .. ->
If no custom zone i
floitsch
2016/07/02 03:11:20
Done.
| |
388 * root zone and [Zone.current] is always identical to [Zone.ROOT]. | |
389 * | |
390 * The root zone implements the default behavior of all zone operations. | |
391 * Many methods, like [registerCallback] do the bare minimum, others, like | |
Lasse Reichstein Nielsen
2016/07/01 11:25:01
... do the bare minimum, and are only provided as
floitsch
2016/07/02 03:11:20
Done.
| |
392 * [scheduleMicrotask] interact with the underlying system to implement the | |
Lasse Reichstein Nielsen
2016/07/01 11:25:01
comma before interact.
floitsch
2016/07/02 03:11:19
Done.
| |
393 * desired behavior. | |
394 */ | |
331 static const Zone ROOT = _ROOT_ZONE; | 395 static const Zone ROOT = _ROOT_ZONE; |
332 | 396 |
333 /** The currently running zone. */ | 397 /** The currently running zone. */ |
334 static Zone _current = _ROOT_ZONE; | 398 static Zone _current = _ROOT_ZONE; |
335 | 399 |
400 /** The zone that is currently active. */ | |
336 static Zone get current => _current; | 401 static Zone get current => _current; |
337 | 402 |
403 /** | |
404 * Handles uncaught asynchronous errors. | |
405 * | |
406 * There are two kind of asynchronous errors that are handled by this | |
407 * function: | |
408 * 1. uncaught errors that were thrown in asynchronous callbacks. For example, | |
Lasse Reichstein Nielsen
2016/07/01 11:25:01
Start with capital letter.
I'd prefer a comma inst
floitsch
2016/07/02 03:11:19
Done.
| |
409 * a `throw` in [Timer.run]. | |
Lasse Reichstein Nielsen
2016/07/01 11:25:02
... a throw in the function passed to [Timer.run].
floitsch
2016/07/02 03:11:19
Done.
| |
410 * 2. asynchronous errors that are pushed down [Future] and [Stream] chains | |
Lasse Reichstein Nielsen
2016/07/01 11:25:01
Start with capital letter again.
maybe: down -> th
floitsch
2016/07/02 03:11:20
Done.
| |
411 * but for which no child registered an error handled. | |
Lasse Reichstein Nielsen
2016/07/01 11:25:01
Comma before but (it's optional, but I would prefe
floitsch
2016/07/02 03:11:19
Done.
| |
412 * Most asynchronous classes, like [Future] or [Stream] push errors to their | |
413 * listeners. Errors are propagated this way until either a listener handles | |
414 * the error (for example with [Future.catchError]), or no listener is | |
415 * available anymore. In the latter case, futures and streams invoke the | |
416 * zone's [handleUncaughtError]. | |
417 * | |
418 * By default, when handled by the root zone, uncaught asynchronous errors are | |
419 * treated like synchronous uncaught exceptions. | |
Lasse Reichstein Nielsen
2016/07/01 11:25:01
I'd say "uncaught synchronous exceptions".
I just
floitsch
2016/07/02 03:11:19
Done.
| |
420 */ | |
338 /*=R*/ handleUncaughtError/*<R>*/(error, StackTrace stackTrace); | 421 /*=R*/ handleUncaughtError/*<R>*/(error, StackTrace stackTrace); |
339 | 422 |
340 /** | 423 /** |
341 * Returns the parent zone. | 424 * Returns the parent zone. |
Lasse Reichstein Nielsen
2016/07/01 11:25:01
Describe a getter like a property, not a method. I
floitsch
2016/07/02 03:11:20
Done.
| |
342 * | 425 * |
343 * Returns `null` if `this` is the [ROOT] zone. | 426 * Returns `null` if `this` is the [ROOT] zone. |
Lasse Reichstein Nielsen
2016/07/01 11:25:01
-> Is `null` if ...
floitsch
2016/07/02 03:11:20
Done.
| |
427 * | |
428 * Zones are created by [fork] on an existing zone, or by [runZoned] which | |
429 * forks the [current] zone. The new zone's parent zone is the zone it was | |
430 * forked from. | |
344 */ | 431 */ |
345 Zone get parent; | 432 Zone get parent; |
346 | 433 |
347 /** | 434 /** |
348 * The error zone is the one that is responsible for dealing with uncaught | 435 * The error zone is the one that is responsible for dealing with uncaught |
349 * errors. | 436 * errors. |
350 * Errors are not allowed to cross between zones with different error-zones. | 437 * |
351 * | 438 * This is the closest parent zone of this zone that provides a |
352 * This is the closest parent or ancestor zone of this zone that has a custom | |
353 * [handleUncaughtError] method. | 439 * [handleUncaughtError] method. |
440 * | |
441 * Asynchronous errors never cross zone boundaries between zones with | |
442 * different error handlers. | |
443 * | |
444 * Example: | |
445 * ``` | |
446 * import 'dart:async'; | |
447 * | |
448 * main() { | |
449 * var future; | |
450 * runZoned(() { | |
451 * // The asynchronous error is caught by the custom zone which prints | |
452 * // 'asynchronous error'. | |
453 * future = new Future.error("asynchronous error"); | |
454 * }, onError: (e) { print(e); }); // Creates a zone with an error handler. | |
455 * // The following `catchError` handler is never invoked, because the | |
456 * // custom zone created by the call to `runZoned` provides an | |
457 * // error handler. | |
458 * future.catchError((e) { throw "is never reached"; }); | |
459 * } | |
460 * ``` | |
461 * | |
462 * Note that errors can not enter a child zone with a different error handler | |
Lasse Reichstein Nielsen
2016/07/01 11:25:01
can not -> cannot (or can't).
floitsch
2016/07/02 03:11:20
Done.
| |
463 * either: | |
464 * ``` | |
465 * import 'dart:async'; | |
466 * | |
467 * main() { | |
468 * runZoned(() { | |
469 * // The following asynchronous error is *not* caught by the `catchError` | |
470 * // in the nested zone, since errors are not to cross zone boundaries | |
471 * // with different error handlers. | |
472 * // Instead the error is handled by the current error handler, | |
473 * // printing "Caught by outer zone: asynchronous error". | |
474 * var future = new Future.error("asynchronous error"); | |
475 * runZoned(() { | |
476 * future.catchError((e) { throw "is never reached"; }); | |
477 * }, onError: (e) { throw "is never reached"; }); | |
478 * }, onError: (e) { print("Caught by outer zone: $e"); }); | |
479 * } | |
480 * ``` | |
354 */ | 481 */ |
355 Zone get errorZone; | 482 Zone get errorZone; |
356 | 483 |
357 /** | 484 /** |
358 * Returns true if `this` and [otherZone] are in the same error zone. | 485 * Returns true if `this` and [otherZone] are in the same error zone. |
359 * | 486 * |
360 * Two zones are in the same error zone if they inherit their | 487 * Two zones are in the same error zone if they have the same [errorZone]. |
361 * [handleUncaughtError] callback from the same [errorZone]. | |
362 */ | 488 */ |
363 bool inSameErrorZone(Zone otherZone); | 489 bool inSameErrorZone(Zone otherZone); |
364 | 490 |
365 /** | 491 /** |
366 * Creates a new zone as a child of `this`. | 492 * Creates a new zone as a child of `this`. |
367 * | 493 * |
368 * The new zone will have behavior like the current zone, except where | 494 * The new zone uses the closures in the given [specification] to override |
369 * overridden by functions in [specification]. | 495 * the current's zone behavior. All specification entries that are `null` |
370 * | 496 * inherit the behavior from the parent zone (`this`). |
371 * The new zone will have the same stored values (accessed through | 497 * |
372 * `operator []`) as this zone, but updated with the keys and values | 498 * The new zone inherits the stored values (accessed through `operator []`) |
Lasse Reichstein Nielsen
2016/07/04 14:14:19
[operator []]
(if you can write that in DartDoc
floitsch
2016/07/05 15:39:57
Dartdoc doesn't link it, but at least doesn't "bre
| |
373 * in [zoneValues]. If a key is in both this zone's values and in | 499 * of this zone and updates them with values from [zoneValues], which either |
374 * `zoneValues`, the new zone will use the value from `zoneValues``. | 500 * adds new values or overrides existing ones. |
375 */ | 501 * |
376 Zone fork({ ZoneSpecification specification, | 502 * Note that the fork operation is interceptible. A zone can thus change |
377 Map zoneValues }); | 503 * the zone specification (or zone values), giving the forking zone full |
378 | 504 * control over the child zone. |
379 /** | 505 */ |
380 * Executes the given function [f] in this zone. | 506 Zone fork({ZoneSpecification specification, |
381 */ | 507 Map zoneValues}); |
382 /*=R*/ run/*<R>*/(/*=R*/ f()); | 508 |
383 | 509 /** |
384 /** | 510 * Executes [action] in this zone. |
385 * Executes the given callback [f] with argument [arg] in this zone. | 511 * |
386 */ | 512 * By default (as implemented in the [ROOT] zone), runs [action] |
387 /*=R*/ runUnary/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg); | 513 * with [current] set to this zone. |
388 | 514 * |
389 /** | 515 * If [action] throws, the synchronous exception is not caught by the zone's |
390 * Executes the given callback [f] with argument [arg1] and [arg2] in this | 516 * error handler. Use [runGuarded] to achieve that. |
517 * | |
518 * Since the root zone is the only zone that can modify the value of | |
519 * [current], custom zones intercepting run should always delegate to their | |
520 * parent zone. They may take actions before and after the call. | |
521 */ | |
522 /*=R*/ run/*<R>*/(/*=R*/ action()); | |
523 | |
524 /** | |
525 * Executes the given [action] with [argument] in this zone. | |
526 * | |
527 * As [run] except that [action] is called with one [argument] instead of | |
528 * none. | |
529 */ | |
530 /*=R*/ runUnary/*<R, T>*/(/*=R*/ action(/*=T*/ argument), /*=T*/ argument); | |
531 | |
532 /** | |
533 * Executes the given [action] with [argument1] and [argument2] in this | |
391 * zone. | 534 * zone. |
535 * | |
536 * As [run] except that [action] is called with two arguments instead of none. | |
392 */ | 537 */ |
393 /*=R*/ runBinary/*<R, T1, T2>*/( | 538 /*=R*/ runBinary/*<R, T1, T2>*/( |
394 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2); | 539 /*=R*/ action(/*=T1*/ argument1, /*=T2*/ argument2), /*=T1*/ argument1, |
395 | 540 /*=T2*/ argument2); |
396 /** | 541 |
397 * Executes the given function [f] in this zone. | 542 /** |
398 * | 543 * Executes the given [action] in this zone and catches synchronous |
399 * Same as [run] but catches uncaught errors and gives them to | 544 * errors. |
400 * [handleUncaughtError]. | 545 * |
401 */ | 546 * This function is equivalent to: |
402 /*=R*/ runGuarded/*<R>*/(/*=R*/ f()); | 547 * ``` |
403 | 548 * try { |
404 /** | 549 * return this.run(action); |
405 * Executes the given callback [f] in this zone. | 550 * } catch (e, s) { |
406 * | 551 * return this.handleUncaughtError(e, s); |
407 * Same as [runUnary] but catches uncaught errors and gives them to | 552 * } |
408 * [handleUncaughtError]. | 553 * ``` |
409 */ | 554 * |
410 /*=R*/ runUnaryGuarded/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg); | 555 * See [run]. |
411 | 556 */ |
412 /** | 557 /*=R*/ runGuarded/*<R>*/(/*=R*/ action()); |
413 * Executes the given callback [f] in this zone. | 558 |
414 * | 559 /** |
415 * Same as [runBinary] but catches uncaught errors and gives them to | 560 * Executes the given [action] with [argument] in this zone and |
416 * [handleUncaughtError]. | 561 * catches synchronous errors. |
562 * | |
563 * See [runGuarded]. | |
564 */ | |
565 /*=R*/ runUnaryGuarded/*<R, T>*/(/*=R*/ action(/*=T*/ argument), | |
566 /*=T*/ argument); | |
567 | |
568 /** | |
569 * Executes the given [action] with [argument1] and [argument2] in this | |
570 * zone and catches synchronous errors. | |
571 * | |
572 * See [runGuarded]. | |
417 */ | 573 */ |
418 /*=R*/ runBinaryGuarded/*<R, T1, T2>*/( | 574 /*=R*/ runBinaryGuarded/*<R, T1, T2>*/( |
419 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2); | 575 /*=R*/ action(/*=T1*/ argument1, /*=T2*/ argument2), /*=T1*/ argument1, |
576 /*=T2*/ argument2); | |
420 | 577 |
421 /** | 578 /** |
422 * Registers the given callback in this zone. | 579 * Registers the given callback in this zone. |
423 * | 580 * |
424 * It is good practice to register asynchronous or delayed callbacks before | 581 * When implementing an asynchronous primitive that uses callbacks, the |
425 * invoking [run]. This gives the zone a chance to wrap the callback and | 582 * callback must be registered using [registerCallback] at the point where the |
426 * to store information with the callback. For example, a zone may decide | 583 * user provides the callback. This allows zones to record other information |
584 * that they need at the same time, perhaps even wrapping the callback, so | |
585 * that the callback is prepared when it is later run in the same zones | |
586 * (using [run]). For example, a zone may decide | |
427 * to store the stack trace (at the time of the registration) with the | 587 * to store the stack trace (at the time of the registration) with the |
428 * callback. | 588 * callback. |
429 * | 589 * |
430 * Returns a potentially new callback that should be used in place of the | 590 * Returns the callback that should be used in place of the provided |
431 * given [callback]. | 591 * [callback]. Frequently zones simply return the original callback. |
592 * | |
593 * Custom zones may intercept this operation. The default implementation in | |
594 * [Zone.ROOT] returns the original callback unchanged. | |
432 */ | 595 */ |
433 ZoneCallback/*<R>*/ registerCallback/*<R>*/(/*=R*/ callback()); | 596 ZoneCallback/*<R>*/ registerCallback/*<R>*/(/*=R*/ callback()); |
434 | 597 |
435 /** | 598 /** |
436 * Registers the given callback in this zone. | 599 * Registers the given callback in this zone. |
437 * | 600 * |
438 * Similar to [registerCallback] but with a unary callback. | 601 * Similar to [registerCallback] but with a unary callback. |
439 */ | 602 */ |
440 ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/( | 603 ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/( |
441 /*=R*/ callback(/*=T*/ arg)); | 604 /*=R*/ callback(/*=T*/ arg)); |
442 | 605 |
443 /** | 606 /** |
444 * Registers the given callback in this zone. | 607 * Registers the given callback in this zone. |
445 * | 608 * |
446 * Similar to [registerCallback] but with a unary callback. | 609 * Similar to [registerCallback] but with a unary callback. |
447 */ | 610 */ |
448 ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/( | 611 ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/( |
449 /*=R*/ callback(/*=T1*/ arg1, /*=T2*/ arg2)); | 612 /*=R*/ callback(/*=T1*/ arg1, /*=T2*/ arg2)); |
450 | 613 |
451 /** | 614 /** |
452 * Equivalent to: | 615 * Equivalent to: |
453 * | 616 * |
454 * ZoneCallback registered = registerCallback(f); | 617 * ZoneCallback registered = this.registerCallback(action); |
455 * if (runGuarded) return () => this.runGuarded(registered); | 618 * if (runGuarded) return () => this.runGuarded(registered); |
456 * return () => this.run(registered); | 619 * return () => this.run(registered); |
457 * | 620 * |
458 */ | 621 */ |
459 ZoneCallback/*<R>*/ bindCallback/*<R>*/( | 622 ZoneCallback/*<R>*/ bindCallback/*<R>*/( |
460 /*=R*/ f(), { bool runGuarded: true }); | 623 /*=R*/ action(), { bool runGuarded: true }); |
461 | 624 |
462 /** | 625 /** |
463 * Equivalent to: | 626 * Equivalent to: |
464 * | 627 * |
465 * ZoneCallback registered = registerUnaryCallback(f); | 628 * ZoneCallback registered = this.registerUnaryCallback(action); |
466 * if (runGuarded) return (arg) => this.runUnaryGuarded(registered, arg); | 629 * if (runGuarded) return (arg) => this.runUnaryGuarded(registered, arg); |
467 * return (arg) => thin.runUnary(registered, arg); | 630 * return (arg) => thin.runUnary(registered, arg); |
468 */ | 631 */ |
469 ZoneUnaryCallback/*<R, T>*/ bindUnaryCallback/*<R, T>*/( | 632 ZoneUnaryCallback/*<R, T>*/ bindUnaryCallback/*<R, T>*/( |
470 /*=R*/ f(/*=T*/ arg), { bool runGuarded: true }); | 633 /*=R*/ action(/*=T*/ argument), { bool runGuarded: true }); |
471 | 634 |
472 /** | 635 /** |
473 * Equivalent to: | 636 * Equivalent to: |
474 * | 637 * |
475 * ZoneCallback registered = registerBinaryCallback(f); | 638 * ZoneCallback registered = registerBinaryCallback(action); |
476 * if (runGuarded) { | 639 * if (runGuarded) { |
477 * return (arg1, arg2) => this.runBinaryGuarded(registered, arg); | 640 * return (arg1, arg2) => this.runBinaryGuarded(registered, arg); |
478 * } | 641 * } |
479 * return (arg1, arg2) => thin.runBinary(registered, arg1, arg2); | 642 * return (arg1, arg2) => thin.runBinary(registered, arg1, arg2); |
480 */ | 643 */ |
481 ZoneBinaryCallback/*<R, T1, T2>*/ bindBinaryCallback/*<R, T1, T2>*/( | 644 ZoneBinaryCallback/*<R, T1, T2>*/ bindBinaryCallback/*<R, T1, T2>*/( |
482 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), { bool runGuarded: true }); | 645 /*=R*/ action(/*=T1*/ argument1, /*=T2*/ argument2), |
646 { bool runGuarded: true }); | |
483 | 647 |
484 /** | 648 /** |
485 * Intercepts errors when added programmatically to a `Future` or `Stream`. | 649 * Intercepts errors when added programatically to a `Future` or `Stream`. |
486 * | 650 * |
487 * When caling [Completer.completeError], [Stream.addError], | 651 * When calling [Completer.completeError], [Stream.addError], |
488 * or [Future] constructors that take an error or a callback that may throw, | 652 * or for some [Future] constructors the current zone is allowed to intercept |
Lasse Reichstein Nielsen
2016/07/01 11:25:01
remove "for". Consider a comma before "the current
floitsch
2016/07/02 03:11:19
Done.
| |
489 * the current zone is allowed to intercept and replace the error. | 653 * and replace the error. |
490 * | 654 * |
491 * When other libraries use intermediate controllers or completers, such | 655 * Future constructors invoke this function when the error is received |
492 * calls may contain errors that have already been processed. | 656 * directly, for example with [Future.error], or when the error is caught |
657 * synchronously, for example with [Future.sync]. | |
493 * | 658 * |
494 * Return `null` if no replacement is desired. | 659 * There is no guarantee that an error is only sent through [errorCallback] |
495 * The original error is used unchanged in that case. | 660 * once. Libraries that use intermediate controllers or completers might |
496 * Otherwise return an instance of [AsyncError] holding | 661 * end up invoking [errorCallback] multiple times. |
497 * the new pair of error and stack trace. | 662 * |
498 * If the [AsyncError.error] is `null`, it is replaced by a [NullThrownError]. | 663 * Returns `null` if no replacement is desired. Otherwise returns an instance |
664 * of [AsyncError] holding the new pair of error and stack trace. | |
665 * | |
666 * Although not recommended, the returned instance may have its `error` member | |
667 * ([AsyncError.error]) be equal to `null` in which case the error should be | |
668 * replaced by a [NullThrownError]. | |
669 * | |
670 * Custom zones may intercept this operation. | |
671 * | |
672 * Implementations of a new asynchronous primitive that converts synchronous | |
673 * errors to asynchronous errors rarely need to invoke [errorCallback], since | |
674 * errors are usually reported through future completers or stream | |
675 * controllers. | |
499 */ | 676 */ |
500 AsyncError errorCallback(Object error, StackTrace stackTrace); | 677 AsyncError errorCallback(Object error, StackTrace stackTrace); |
501 | 678 |
502 /** | 679 /** |
503 * Runs [f] asynchronously in this zone. | 680 * Runs [action] asynchronously in this zone. |
681 * | |
682 * The global `scheduleMicrotask` delegates to the current zone's | |
683 * [scheduleMicrotask]. The root zone's implementation interacts with the | |
684 * underlying system to schedule the given callback as a microtask. | |
685 * | |
686 * Custom zones may intercept this operation (for example to wrap the given | |
687 * callback [action]). | |
504 */ | 688 */ |
505 void scheduleMicrotask(void f()); | 689 void scheduleMicrotask(void action()); |
506 | 690 |
507 /** | 691 /** |
508 * Creates a task, given a [create] function and a [specification]. | 692 * Creates a task in the current zone. |
509 * | 693 * |
510 * The [create] function is invoked with the [specification] as argument. It | 694 * A task represents an asynchronous operation or process that reports back |
511 * returns a task object which is used for all future interactions with the | 695 * through the event loop. |
512 * zone. | |
513 * | 696 * |
514 * Custom zones may replace the [specification] with a different one, thus | 697 * This function allows the zone to intercept the initialization of the |
515 * modifying the task parameters. | 698 * task while the [runTask] function is invoked when the task reports back. |
516 * | 699 * |
517 * Tasks are created when the program is starting an operation that returns | 700 * By default, in the root zone, the [create] function is invoked with the |
518 * through the event loop. For example, a timer or an http request both | 701 * [specification] as argument. It returns a task object which is used for all |
702 * future interactions between the zone and the task. The object is | |
703 * a unique instance representing the task. It is generally returned to | |
704 * whoever initiated the task. | |
705 * For example, the HTML library uses the returned [StreamSubscription] as | |
706 * task object when users register an event listener. | |
707 * | |
708 * Tasks are created when the program starts an operation that reports back | |
709 * through the event loop. For example, a timer or an HTTP request both | |
519 * return through the event loop and are therefore tasks. | 710 * return through the event loop and are therefore tasks. |
520 * | 711 * |
521 * If the [create] function is not invoked (because a custom zone has | 712 * If the [create] function is not invoked (because a custom zone has |
522 * replaced or intercepted it), then the operation is *not* started. This | 713 * replaced or intercepted it), then the operation is *not* started. This |
523 * means that a custom zone can intercept tasks, like http requests. | 714 * means that a custom zone can intercept tasks, like HTTP requests. |
715 * | |
716 * A task goes through the following steps: | |
717 * - a user invokes a library function that should eventually return through | |
718 * the event loop. | |
719 * - the library function creates a [TaskSpecification] that contains the | |
720 * necessary information to start the operation, and invokes | |
721 * `Zone.current.createTask` with the specification and a [create] closure. | |
722 * The closure, when invoked, uses the specification to start the operation | |
723 * (usually by interacting with the underlying system, or as a native | |
724 * extension), and returns a task object that identifies the running task. | |
725 * - custom zones handle the request and (unless completely intercepted and | |
726 * aborted), end up calling the root zone's [createTask] which runs the | |
727 * provided `create` closure, which may have been replaced at this point. | |
728 * - later, the asynchronous operation returns through the event loop. | |
729 * It invokes [Zone.runTask] on the zone in which the task should run | |
730 * (and which was originally passed to the `create` function by | |
731 * `createTask`). The [runTask] function receives the | |
732 * task object, a `run` function and an argument. As before, custom zones | |
733 * may intercept this call. Eventually (unless aborted), the `run` function | |
734 * is invoked. This last step may happen multiple times for tasks that are | |
735 * not oneshot tasks (see [ZoneSpecification.isOneShot]). | |
736 * | |
737 * Custom zones may replace the [specification] with a different one, thus | |
738 * modifying the task parameters. An operation that wishes to be an | |
739 * interceptable task must publicly specify the types that intercepting code | |
740 * sees: | |
741 * - The specification type (extending [TaskSpecification]) which holds the | |
742 * information available when intercepting the `createTask` call. | |
743 * - The task object type, returned by `createTask` and [create]. This object | |
744 * may simply be typed as [Object]. | |
745 * - The argument type, if [runTask] takes a meaningful argument. | |
524 * | 746 * |
525 * *Experimental*. Might disappear without notice. | 747 * *Experimental*. Might disappear without notice. |
526 */ | 748 */ |
527 Object/*=T*/ createTask/*<T, S>*/( | 749 Object/*=T*/ createTask/*<T, S extends TaskSpecification>*/( |
528 TaskCreate/*<T, S>*/ create, TaskSpecification/*=S*/ specification); | 750 /*=T*/ create(S specification, Zone zone), |
751 TaskSpecification/*=S*/ specification); | |
529 | 752 |
530 /** | 753 /** |
531 * Runs a task callback. | 754 * Runs a task callback. |
532 * | 755 * |
533 * This function is invoked, when an operation, started through [createTask], | 756 * This function is invoked when an operation, started through [createTask], |
534 * returns to Dart code. | 757 * returns to Dart code. |
535 * | 758 * |
536 * Generally, tasks schedule Dart code in the global event loop. As such, | 759 * Generally, tasks schedule Dart code in the global event loop. As such, |
537 * there is no return value, and [runTask] is a void function. | 760 * there is no return value, and [runTask] is a void function. |
538 * | 761 * |
539 * The [task] object must be the same as the one created with [createTask]. | 762 * The [task] object must be the same as the one created with [createTask]. |
540 * | 763 * |
541 * It is good practice, if task operations provide a meaningful [arg], so | 764 * It is good practice, if task operations provide a meaningful [argument], so |
542 * that custom zones can deal with it. They might want to log it, or | 765 * that custom zones can deal with it. They might want to log it, or |
543 * replace it. | 766 * replace it. |
544 * | 767 * |
768 * See [createTask]. | |
769 * | |
545 * *Experimental*. Might disappear without notice. | 770 * *Experimental*. Might disappear without notice. |
546 */ | 771 */ |
547 void runTask/*<T, A>*/( | 772 void runTask/*<T, A>*/( |
548 TaskRun/*<T, A>*/ run, Object/*=T*/ task, Object/*=A*/ arg); | 773 /*=T*/ run(/*=T*/ task, /*=A*/ argument), Object/*=T*/ task, |
774 Object/*=A*/ argument); | |
549 | 775 |
550 /** | 776 /** |
551 * Creates a Timer where the callback is executed in this zone. | 777 * Creates a Timer where the callback is executed in this zone. |
552 */ | 778 */ |
553 // TODO(floitsch): deprecate once tasks are non-experimental. | 779 // TODO(floitsch): deprecate once tasks are non-experimental. |
554 Timer createTimer(Duration duration, void callback()); | 780 Timer createTimer(Duration duration, void callback()); |
555 | 781 |
556 /** | 782 /** |
557 * Creates a periodic Timer where the callback is executed in this zone. | 783 * Creates a periodic Timer where the callback is executed in this zone. |
558 */ | 784 */ |
559 // TODO(floitsch): deprecate once tasks are non-experimental. | 785 // TODO(floitsch): deprecate once tasks are non-experimental. |
560 Timer createPeriodicTimer(Duration period, void callback(Timer timer)); | 786 Timer createPeriodicTimer(Duration period, void callback(Timer timer)); |
561 | 787 |
562 /** | 788 /** |
563 * Prints the given [line]. | 789 * Prints the given [line]. |
790 * | |
791 * The global `print` function delegates to the current zone's [print] | |
792 * function which makes it possible to intercept printing. | |
793 * | |
794 * Example: | |
795 * ``` | |
796 * import 'dart:async'; | |
797 * | |
798 * main() { | |
799 * runZoned(() { | |
800 * // Ends up printing: "Intercepted: in zone". | |
801 * print("in zone"); | |
802 * }, zoneSpecification: new ZoneSpecification( | |
803 * print: (Zone self, ZoneDelegate parent, Zone zone, String line) { | |
804 * parent.print(zone, "Intercepted: $line"); | |
805 * })); | |
806 * } | |
807 * ``` | |
564 */ | 808 */ |
565 void print(String line); | 809 void print(String line); |
566 | 810 |
567 /** | 811 /** |
568 * Call to enter the Zone. | 812 * Call to enter the Zone. |
569 * | 813 * |
570 * The previous current zone is returned. | 814 * The previous current zone is returned. |
571 */ | 815 */ |
572 static Zone _enter(Zone zone) { | 816 static Zone _enter(Zone zone) { |
573 assert(zone != null); | 817 assert(zone != null); |
(...skipping 955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1529 handleUncaughtError: errorHandler); | 1773 handleUncaughtError: errorHandler); |
1530 } | 1774 } |
1531 Zone zone = Zone.current.fork(specification: zoneSpecification, | 1775 Zone zone = Zone.current.fork(specification: zoneSpecification, |
1532 zoneValues: zoneValues); | 1776 zoneValues: zoneValues); |
1533 if (onError != null) { | 1777 if (onError != null) { |
1534 return zone.runGuarded(body); | 1778 return zone.runGuarded(body); |
1535 } else { | 1779 } else { |
1536 return zone.run(body); | 1780 return zone.run(body); |
1537 } | 1781 } |
1538 } | 1782 } |
OLD | NEW |