Chromium Code Reviews| 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 |