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 typedef T TaskCreate<T, S extends TaskSpecification>( | 11 typedef T TaskCreate<T, S extends TaskSpecification>( |
| 11 S specification, Zone zone); | 12 S specification, Zone zone); |
| 12 typedef void TaskRun<T, A>(T task, A arg); | 13 typedef void TaskRun<T, A>(T task, A arg); |
| 13 | 14 |
| 14 | 15 |
| 15 // TODO(floitsch): we are abusing generic typedefs as typedefs for generic | 16 // TODO(floitsch): we are abusing generic typedefs as typedefs for generic |
| 16 // functions. | 17 // functions. |
| 17 /*ABUSE*/ | 18 /*ABUSE*/ |
| 18 typedef R HandleUncaughtErrorHandler<R>( | 19 typedef R HandleUncaughtErrorHandler<R>( |
| 19 Zone self, ZoneDelegate parent, Zone zone, error, StackTrace stackTrace); | 20 Zone self, ZoneDelegate parent, Zone zone, error, StackTrace stackTrace); |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 252 final PrintHandler print; | 253 final PrintHandler print; |
| 253 final ForkHandler fork; | 254 final ForkHandler fork; |
| 254 | 255 |
| 255 @deprecated | 256 @deprecated |
| 256 final CreateTimerHandler createTimer; | 257 final CreateTimerHandler createTimer; |
| 257 @deprecated | 258 @deprecated |
| 258 final CreatePeriodicTimerHandler createPeriodicTimer; | 259 final CreatePeriodicTimerHandler createPeriodicTimer; |
| 259 } | 260 } |
| 260 | 261 |
| 261 /** | 262 /** |
| 262 * This class wraps zones for delegation. | 263 * This class wraps zones for delegation. |
|
Lasse Reichstein Nielsen
2016/06/20 21:19:16
Doesn't make sense.
You can wrap a zone, but not (
floitsch
2016/07/01 04:03:40
Done.
| |
| 263 * | 264 * |
| 264 * When forwarding to parent zones one can't just invoke the parent zone's | 265 * Custom zones (created through `Zone.fork` or `runZoned`) can provide |
| 265 * exposed functions (like [Zone.run]), but one needs to provide more | 266 * implementations of most members of zones. This is similar to overriding |
|
Lasse Reichstein Nielsen
2016/06/20 21:19:15
members of `Zone`?
"members" feels weird, since t
floitsch
2016/07/01 04:03:38
Done.
| |
| 266 * information (like the zone the `run` was initiated). Zone callbacks thus | 267 * methods on [Zone], except that this mechanism doesn't require subclassing. |
| 267 * receive more information including this [ZoneDelegate] class. When delegating | 268 * |
| 268 * to the parent zone one should go through the given instance instead of | 269 * A very common operation of intercepting function is to eventually delegate |
|
Lasse Reichstein Nielsen
2016/06/20 21:19:16
Drop "very".
intercepting functions?
But "interce
floitsch
2016/07/01 04:03:38
Done.
| |
| 269 * directly invoking the parent zone. | 270 * to its parent zone. Intercepting functions receive a parent delegate (of |
| 271 * type [ZoneDelegate] for this purpose. | |
| 272 * | |
| 273 * Providing zone delegates to intercepting functions has two advantages: | |
|
Lasse Reichstein Nielsen
2016/06/20 21:19:16
I don't think this belongs in user-directed docume
floitsch
2016/07/01 04:03:40
Reworded.
| |
| 274 * 1. the intercepting function can provide more information to the parent zone. | |
| 275 * In particular it has to provide the zone in which the action has been | |
| 276 * initiated. | |
| 277 * 2. The library can implement the delegates in a more efficient way, since | |
| 278 * it can skip zones that would just delegate to their parents. | |
| 279 * | |
| 280 * As mentioned in advantage 1, delegates receive a additional arguments. | |
| 281 * CONTINUE HERE. | |
| 270 */ | 282 */ |
| 271 abstract class ZoneDelegate { | 283 abstract class ZoneDelegate { |
| 272 /*=R*/ handleUncaughtError/*<R>*/( | 284 /*=R*/ handleUncaughtError/*<R>*/( |
| 273 Zone zone, error, StackTrace stackTrace); | 285 Zone zone, error, StackTrace stackTrace); |
| 274 /*=R*/ run/*<R>*/(Zone zone, /*=R*/ f()); | 286 /*=R*/ run/*<R>*/(Zone zone, /*=R*/ f()); |
| 275 /*=R*/ runUnary/*<R, T>*/(Zone zone, /*=R*/ f(/*=T*/ arg), /*=T*/ arg); | 287 /*=R*/ runUnary/*<R, T>*/(Zone zone, /*=R*/ f(/*=T*/ arg), /*=T*/ arg); |
| 276 /*=R*/ runBinary/*<R, T1, T2>*/(Zone zone, | 288 /*=R*/ runBinary/*<R, T1, T2>*/(Zone zone, |
| 277 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2); | 289 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2); |
| 278 ZoneCallback/*<R>*/ registerCallback/*<R>*/(Zone zone, /*=R*/ f()); | 290 ZoneCallback/*<R>*/ registerCallback/*<R>*/(Zone zone, /*=R*/ f()); |
| 279 ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/( | 291 ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/( |
| 280 Zone zone, /*=R*/ f(/*=T*/ arg)); | 292 Zone zone, /*=R*/ f(/*=T*/ arg)); |
| 281 ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/( | 293 ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/( |
| 282 Zone zone, /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2)); | 294 Zone zone, /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2)); |
| 283 AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace); | 295 AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace); |
| 284 void scheduleMicrotask(Zone zone, void f()); | 296 void scheduleMicrotask(Zone zone, void f()); |
| 285 Object/*=T*/ createTask/*<T, S>*/( | 297 Object/*=T*/ createTask/*<T, S>*/( |
| 286 Zone zone, TaskCreate/*<T, S>*/ create, TaskSpecification/*=S*/ task); | 298 Zone zone, TaskCreate/*<T, S>*/ create, TaskSpecification/*=S*/ task); |
| 287 void runTask/*T, A*/( | 299 void runTask/*T, A*/( |
| 288 Zone zone, TaskRun/*<T, A>*/ run, Object/*=T*/ task, Object/*=A*/ arg); | 300 Zone zone, TaskRun/*<T, A>*/ run, Object/*=T*/ task, Object/*=A*/ arg); |
| 289 void print(Zone zone, String line); | 301 void print(Zone zone, String line); |
| 290 Zone fork(Zone zone, ZoneSpecification specification, Map zoneValues); | 302 Zone fork(Zone zone, ZoneSpecification specification, Map zoneValues); |
| 291 | 303 |
| 292 @deprecated | 304 @deprecated |
| 293 Timer createTimer(Zone zone, Duration duration, void f()); | 305 Timer createTimer(Zone zone, Duration duration, void f()); |
| 294 @deprecated | 306 @deprecated |
| 295 Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)); | 307 Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)); |
| 296 } | 308 } |
| 297 | 309 |
| 298 /** | 310 /** |
| 299 * A Zone represents the asynchronous version of a dynamic extent. Asynchronous | 311 * A Zone represents an environment that remains stable across asynchronous |
|
Lasse Reichstein Nielsen
2016/06/20 21:19:16
`Zone`
floitsch
2016/07/01 04:03:39
changed to 'zone'.
| |
| 300 * callbacks are executed in the zone they have been queued in. For example, | 312 * calls, and which is responsible for handling uncaught asynchronous errors, |
|
Lasse Reichstein Nielsen
2016/06/20 21:19:16
Full stop after "calls", then new paragraph.
The
floitsch
2016/07/01 04:03:38
Incorporated (partially) your text.
| |
| 301 * the callback of a `future.then` is executed in the same zone as the one where | 313 * or operations such as [print] and [scheduleMicrotask]. |
| 302 * the `then` was invoked. | 314 * |
| 315 * Asynchronous callbacks are executed in the zone they have been queued in. For | |
| 316 * example, the callback of a `future.then` is executed in the same zone as the | |
| 317 * one where the `then` was invoked. | |
| 318 * | |
| 319 * Code is always executed inside a zone. When a program is started, the | |
|
Lasse Reichstein Nielsen
2016/06/20 21:19:16
"inside" feels a little too concrete for me.
How a
floitsch
2016/07/01 04:03:39
Done.
| |
| 320 * default zone ([Zone.ROOT]) is installed. Users can provide | |
| 321 * shadowing, nested zones. | |
| 322 * | |
| 323 * The [Zone] class is not subclassable, but users can provide custom zones by | |
| 324 * forking an existing zone (usually [Zone.current]) with a [ZoneSpecification]. | |
| 325 * Zone specifications contain intercepting functions that are invoked when the | |
| 326 * zone members are invoked. As such, they provide the same functionality as | |
| 327 * subclassing (but allow for a more efficient implementation). | |
| 328 * | |
| 329 * Asynchronous callbacks always return in the zone in which they have been | |
|
Lasse Reichstein Nielsen
2016/06/20 21:19:16
have been -> are
callbacks are functions, when yo
floitsch
2016/07/01 04:03:38
Done.
| |
| 330 * scheduled. This happens in two steps: | |
| 331 * - the callback is registered using one of [registerCallback], | |
| 332 * [registerUnaryCallback], or [registerBinaryCallback]. | |
| 333 * - the asynchronous operation (such as [Future.then] or [Stream.listen]) | |
| 334 * remember the current zone. Either, they store the zone in a data structure | |
| 335 * (as is done for [Future]s), or they wrap the callback to capture the | |
| 336 * current zone. A convenience function [bindCallback] (and the corresponding | |
| 337 * [bindUnaryCallback] or [bindBindaryCallback]) perform the registration and | |
| 338 * wrapping at the same time. | |
| 339 * | |
| 340 * Note that all asynchronous primitives (like [Timer.run]) have to be | |
| 341 * implemented by the embedder, and that users generally don't need to worry | |
| 342 * about keeping track of zones. However, new embedders (or native extensions) | |
| 343 * need to ensure that new asynchronous primitives (like for example | |
| 344 * `requestAnimationFrame` in the HTML library) respect this contract. | |
| 303 */ | 345 */ |
| 304 abstract class Zone { | 346 abstract class Zone { |
| 305 // Private constructor so that it is not possible instantiate a Zone class. | 347 // Private constructor so that it is not possible instantiate a Zone class. |
| 306 Zone._(); | 348 Zone._(); |
| 307 | 349 |
| 308 /** The root zone that is implicitly created. */ | 350 /** |
| 351 * The root zone that is implicitly created. | |
|
Lasse Reichstein Nielsen
2016/06/20 21:19:16
The root zone.
This is the zone that the isolate
floitsch
2016/07/01 04:03:39
somehow incorporated.
| |
| 352 * | |
| 353 * The root zone implements the default behavior of all zone operations. | |
| 354 * Many methods, like [registerCallback] don't do anything, others, like | |
| 355 * [scheduleMicrotask] interact with the embedder to implement the desired | |
| 356 * behavior. | |
| 357 */ | |
| 309 static const Zone ROOT = _ROOT_ZONE; | 358 static const Zone ROOT = _ROOT_ZONE; |
| 310 | 359 |
| 311 /** The currently running zone. */ | 360 /** The currently running zone. */ |
| 312 static Zone _current = _ROOT_ZONE; | 361 static Zone _current = _ROOT_ZONE; |
| 313 | 362 |
| 363 /** The zone that is currently active. */ | |
| 314 static Zone get current => _current; | 364 static Zone get current => _current; |
| 315 | 365 |
| 366 /** | |
| 367 * Handles uncaught asynchronous errors. | |
| 368 * | |
| 369 * Most asynchronous classes, like [Future] or [Stream] push errors to their | |
| 370 * listeners. Errors are propagated this way, until, either a listener handles | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:01
remove both commas.
floitsch
2016/07/01 04:03:39
Done.
| |
| 371 * the error (for example with [Future.catchError]), or no listener is | |
| 372 * available anymore. In the latter case, futures and streams invoke the | |
| 373 * zone's [handleUncaughtError]. | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
Mention that we also handle uncuaght errors from o
floitsch
2016/07/01 04:03:39
Reworded.
| |
| 374 * | |
| 375 * By default, in the root zone, uncaught asynchronous errors are treated | |
| 376 * like synchronous uncaught exceptions (although the root zone defers the | |
| 377 * reporting by a microtask, to give other microtasks the opportunity to run | |
| 378 * one last time). | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
Actually not.
An uncaught error that hits the unca
floitsch
2016/07/01 04:03:38
Removed the mention of microtask.
| |
| 379 */ | |
| 316 /*=R*/ handleUncaughtError/*<R>*/(error, StackTrace stackTrace); | 380 /*=R*/ handleUncaughtError/*<R>*/(error, StackTrace stackTrace); |
| 317 | 381 |
| 318 /** | 382 /** |
| 319 * Returns the parent zone. | 383 * Returns the parent zone. |
| 320 * | 384 * |
| 321 * Returns `null` if `this` is the [ROOT] zone. | 385 * Returns `null` if `this` is the [ROOT] zone. |
| 386 * | |
| 387 * Zones are created by [fork] (or [runZoned] which forks the [current] zone) | |
| 388 * on an existing zone. The new zone keeps the forking zone as [parent] zone. | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:01
Move parentheses to after "an existing zone". Mayb
floitsch
2016/07/01 04:03:39
I don't know anymore why it was added. Probably be
| |
| 322 */ | 389 */ |
| 323 Zone get parent; | 390 Zone get parent; |
| 324 | 391 |
| 325 /** | 392 /** |
| 326 * The error zone is the one that is responsible for dealing with uncaught | 393 * The error zone is the one that is responsible for dealing with uncaught |
| 327 * errors. | 394 * errors. |
| 328 * Errors are not allowed to cross between zones with different error-zones. | |
| 329 * | 395 * |
| 330 * This is the closest parent or ancestor zone of this zone that has a custom | 396 * This is the closest parent zone of this zone that provides a |
| 331 * [handleUncaughtError] method. | 397 * [handleUncaughtError] method. |
| 398 * | |
| 399 * Asynchronous errors never cross zone boundaries of zones with different | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:02
... boundaries between zones ...
floitsch
2016/07/01 04:03:38
Done.
| |
| 400 * error-zones. | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
error-zones -> error handlers.
floitsch
2016/07/01 04:03:39
Done.
| |
| 401 * | |
| 402 * Example: | |
| 403 * ``` | |
| 404 * import 'dart:async'; | |
| 405 * | |
| 406 * main() { | |
| 407 * var future; | |
| 408 * runZoned(() { | |
| 409 * // The asynchronous error is caught by the custom zone which prints | |
| 410 * // 'asynchronous error'. | |
| 411 * future = new Future.error("asynchronous error"); | |
| 412 * }, onError: (e) { print(e); }); // Creates a zone with an error handler. | |
| 413 * // The following `catchError` is never reached, because the custom zone | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:02
is never reached -> never sees the error
(sounds
floitsch
2016/07/01 04:03:38
Done.
| |
| 414 * // that is created by the call to `runZoned` provides an error handler. | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
-> custom zone created by `runZoned`
(just becaus
floitsch
2016/07/01 04:03:39
Done.
| |
| 415 * future.catchError((e) { throw "is never reached"; }); | |
| 416 * } | |
| 417 * ``` | |
| 418 * | |
| 419 * Note that errors are not entering zones with different error handlers | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
are not entering -> cannot enter
Maybe: *enter*
(
floitsch
2016/07/01 04:03:40
Done.
| |
| 420 * either: | |
| 421 * ``` | |
| 422 * import 'dart:async'; | |
| 423 * | |
| 424 * main() { | |
| 425 * runZoned(() { | |
| 426 * // The following asynchronous error is *not* caught by the `catchError` | |
| 427 * // in the nested zone, since errors are not to cross zone boundaries | |
| 428 * // with different error handlers. | |
| 429 * // Instead the error is handled by the current error handler, | |
| 430 * // printing "Caught by outer zone: asynchronous error". | |
| 431 * var future = new Future.error("asynchronous error"); | |
| 432 * runZoned(() { | |
| 433 * future.catchError((e) { throw "is never reached"; }); | |
| 434 * }, onError: (e) { throw "is never reached"; }); | |
| 435 * }, onError: (e) { print("Caught by outer zone: $e"); }); | |
| 436 * } | |
| 437 * ``` | |
| 332 */ | 438 */ |
| 333 Zone get errorZone; | 439 Zone get errorZone; |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:02
And this shouldn't be public either. :)
floitsch
2016/07/01 04:03:39
That one is definitely used in the async library.
| |
| 334 | 440 |
| 335 /** | 441 /** |
| 336 * Returns true if `this` and [otherZone] are in the same error zone. | 442 * Returns true if `this` and [otherZone] are in the same error zone. |
| 337 * | 443 * |
| 338 * Two zones are in the same error zone if they inherit their | 444 * Two zones are in the same error zone if they inherit their |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
Rewrite: if they have the same [errorZone].
floitsch
2016/07/01 04:03:40
Done.
| |
| 339 * [handleUncaughtError] callback from the same [errorZone]. | 445 * [errorZone] is the same. |
| 340 */ | 446 */ |
| 341 bool inSameErrorZone(Zone otherZone); | 447 bool inSameErrorZone(Zone otherZone); |
| 342 | 448 |
| 343 /** | 449 /** |
| 344 * Creates a new zone as a child of `this`. | 450 * Creates a new zone as a child of `this`. |
| 345 * | 451 * |
| 346 * The new zone will have behavior like the current zone, except where | 452 * The new zone uses the closures in the given [specification] to override |
| 347 * overridden by functions in [specification]. | 453 * the current's zone behavior. All specification entries that are `null` |
| 454 * are automatically delegated to the parent zone (`this`). | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
Maybe: are automatically delegated to -> inherits
floitsch
2016/07/01 04:03:38
Done.
| |
| 348 * | 455 * |
| 349 * The new zone will have the same stored values (accessed through | 456 * The new zone has the same stored values (accessed through |
| 350 * `operator []`) as this zone, but updated with the keys and values | 457 * `operator []`) as this zone, but updated with the keys and values |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
drop "but".
Maybe: The new zone inherits the store
floitsch
2016/07/01 04:03:40
Done.
| |
| 351 * in [zoneValues]. If a key is in both this zone's values and in | 458 * in [zoneValues]. If a key is in both this zone's values and in |
| 352 * `zoneValues`, the new zone will use the value from `zoneValues``. | 459 * `zoneValues`, the new zone uses the value from `zoneValues`. |
| 460 * | |
| 461 * Note that the fork operation is interceptible. A zone can thus replace | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:02
replace -> change
(change covers both "modify" and
floitsch
2016/07/01 04:03:39
Done.
| |
| 462 * the zone specification (or zone value), giving the parent zone full control | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
value -> values
parent zone -> forking zone
("pare
floitsch
2016/07/01 04:03:40
Done.
| |
| 463 * over the child zone. | |
| 353 */ | 464 */ |
| 354 Zone fork({ ZoneSpecification specification, | 465 Zone fork({ZoneSpecification specification, |
| 355 Map zoneValues }); | 466 Map zoneValues}); |
| 356 | 467 |
| 357 /** | 468 /** |
| 358 * Executes the given function [f] in this zone. | 469 * Executes the given function [f] in this zone. |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
We should rename `f` to `action` or something non-
floitsch
2016/07/01 04:03:40
Done.
| |
| 470 * | |
| 471 * By default (as implemented in the [ROOT] zone, this updates the [current] | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
By default, as implemented in the [ROOT] zone, thi
floitsch
2016/07/01 04:03:39
Done.
| |
| 472 * zone to this zone, and executes [f]. | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:02
Add:
If [action] throws, the synchronous exception
floitsch
2016/07/01 04:03:40
Done.
| |
| 473 * | |
| 474 * Since the root zone is the only zone that can modify the [current] getter, | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
the [current] getter -> the value of [current]
(n
floitsch
2016/07/01 04:03:40
Done.
| |
| 475 * custom zones have to delegate to their parent zone if they wish to run | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:02
custom zone intercepting [run] should always deleg
floitsch
2016/07/01 04:03:38
Done.
| |
| 476 * in their zone (which is generally the recommended behavior). | |
| 359 */ | 477 */ |
| 360 /*=R*/ run/*<R>*/(/*=R*/ f()); | 478 /*=R*/ run/*<R>*/(/*=R*/ f()); |
| 361 | 479 |
| 362 /** | 480 /** |
| 363 * Executes the given callback [f] with argument [arg] in this zone. | 481 * Executes the given callback [f] with argument [arg] in this zone. |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:02
arg -> argument
consider f -> action.
(the "no abb
floitsch
2016/07/01 04:03:39
Done.
| |
| 482 * | |
| 483 * See [run]. | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
As [run] except that [action] is called with one [
floitsch
2016/07/01 04:03:38
Done.
| |
| 364 */ | 484 */ |
| 365 /*=R*/ runUnary/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg); | 485 /*=R*/ runUnary/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg); |
| 366 | 486 |
| 367 /** | 487 /** |
| 368 * Executes the given callback [f] with argument [arg1] and [arg2] in this | 488 * Executes the given callback [f] with argument [arg1] and [arg2] in this |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
Executes [action] with two arguments.
As [run] ex
floitsch
2016/07/01 04:03:38
Done.
| |
| 369 * zone. | 489 * zone. |
| 490 * | |
| 491 * See [run]. | |
| 370 */ | 492 */ |
| 371 /*=R*/ runBinary/*<R, T1, T2>*/( | 493 /*=R*/ runBinary/*<R, T1, T2>*/( |
| 372 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2); | 494 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2); |
| 373 | 495 |
| 374 /** | 496 /** |
| 375 * Executes the given function [f] in this zone. | 497 * Executes the given function [f] in this zone and catches synchronous |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:02
f->action.
floitsch
2016/07/01 04:03:40
Done.
| |
| 498 * errors. | |
| 376 * | 499 * |
| 377 * Same as [run] but catches uncaught errors and gives them to | 500 * This function is equivalent to: |
| 378 * [handleUncaughtError]. | 501 * ``` |
| 502 * try { | |
| 503 * return run(f); | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
consider using "this.run" for emphasiz (and "this.
floitsch
2016/07/01 04:03:39
Done.
| |
| 504 * } catch (e, s) { | |
| 505 * return handleUncaughtError(e, s); | |
| 506 * } | |
| 507 * ``` | |
| 508 * | |
| 509 * See [run]. | |
| 379 */ | 510 */ |
| 380 /*=R*/ runGuarded/*<R>*/(/*=R*/ f()); | 511 /*=R*/ runGuarded/*<R>*/(/*=R*/ f()); |
| 381 | 512 |
| 382 /** | 513 /** |
| 383 * Executes the given callback [f] in this zone. | 514 * Executes the given callback [f] with argument [arg] in this zone and |
| 515 * catches synchronous errors. | |
| 384 * | 516 * |
| 385 * Same as [runUnary] but catches uncaught errors and gives them to | 517 * See [runGuarded]. |
| 386 * [handleUncaughtError]. | |
| 387 */ | 518 */ |
| 388 /*=R*/ runUnaryGuarded/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg); | 519 /*=R*/ runUnaryGuarded/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg); |
| 389 | 520 |
| 390 /** | 521 /** |
| 391 * Executes the given callback [f] in this zone. | 522 * Executes the given callback [f] with arguments [arg1] and [arg2] in this |
| 523 * zone. | |
| 392 * | 524 * |
| 393 * Same as [runBinary] but catches uncaught errors and gives them to | 525 * See [runGuarded]. |
| 394 * [handleUncaughtError]. | |
| 395 */ | 526 */ |
| 396 /*=R*/ runBinaryGuarded/*<R, T1, T2>*/( | 527 /*=R*/ runBinaryGuarded/*<R, T1, T2>*/( |
| 397 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2); | 528 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2); |
| 398 | 529 |
| 399 /** | 530 /** |
| 400 * Registers the given callback in this zone. | 531 * Registers the given callback in this zone. |
| 401 * | 532 * |
| 402 * It is good practice to register asynchronous or delayed callbacks before | 533 * It is good practice to register asynchronous or delayed callbacks before |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:02
"It is good practice" isn't enough. If you don't,
floitsch
2016/07/01 04:03:38
Done.
| |
| 403 * invoking [run]. This gives the zone a chance to wrap the callback and | 534 * invoking [run]. This gives the zone a chance to wrap the callback and |
| 404 * to store information with the callback. For example, a zone may decide | 535 * to store information with the callback. For example, a zone may decide |
| 405 * to store the stack trace (at the time of the registration) with the | 536 * to store the stack trace (at the time of the registration) with the |
| 406 * callback. | 537 * callback. |
| 407 * | 538 * |
| 408 * Returns a potentially new callback that should be used in place of the | 539 * Returns a potentially new callback that should be used in place of the |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:02
Returns the, potentially new, callback that will l
floitsch
2016/07/01 04:03:38
Done.
| |
| 409 * given [callback]. | 540 * given [callback]. |
| 541 * | |
| 542 * Custom zones may intercept this operation. | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:02
Add: The default implementation of [Zone.ROOT] ret
floitsch
2016/07/01 04:03:38
Done.
| |
| 410 */ | 543 */ |
| 411 ZoneCallback/*<R>*/ registerCallback/*<R>*/(/*=R*/ callback()); | 544 ZoneCallback/*<R>*/ registerCallback/*<R>*/(/*=R*/ callback()); |
| 412 | 545 |
| 413 /** | 546 /** |
| 414 * Registers the given callback in this zone. | 547 * Registers the given callback in this zone. |
| 415 * | 548 * |
| 416 * Similar to [registerCallback] but with a unary callback. | 549 * Similar to [registerCallback] but with a unary callback. |
| 417 */ | 550 */ |
| 418 ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/( | 551 ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/( |
| 419 /*=R*/ callback(/*=T*/ arg)); | 552 /*=R*/ callback(/*=T*/ arg)); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 453 * ZoneCallback registered = registerBinaryCallback(f); | 586 * ZoneCallback registered = registerBinaryCallback(f); |
| 454 * if (runGuarded) { | 587 * if (runGuarded) { |
| 455 * return (arg1, arg2) => this.runBinaryGuarded(registered, arg); | 588 * return (arg1, arg2) => this.runBinaryGuarded(registered, arg); |
| 456 * } | 589 * } |
| 457 * return (arg1, arg2) => thin.runBinary(registered, arg1, arg2); | 590 * return (arg1, arg2) => thin.runBinary(registered, arg1, arg2); |
| 458 */ | 591 */ |
| 459 ZoneBinaryCallback/*<R, T1, T2>*/ bindBinaryCallback/*<R, T1, T2>*/( | 592 ZoneBinaryCallback/*<R, T1, T2>*/ bindBinaryCallback/*<R, T1, T2>*/( |
| 460 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), { bool runGuarded: true }); | 593 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), { bool runGuarded: true }); |
| 461 | 594 |
| 462 /** | 595 /** |
| 463 * Intercepts errors when added programmatically to a `Future` or `Stream`. | 596 * Intercepts errors when added programatically to a `Future` or `Stream`. |
| 464 * | 597 * |
| 465 * When caling [Completer.completeError], [Stream.addError], | 598 * When calling [Completer.completeError], [Stream.addError], |
| 466 * or [Future] constructors that take an error or a callback that may throw, | 599 * or [Future] constructors that take an error or a callback that may throw, |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
that take a callback that may throw synchronously,
floitsch
2016/07/01 04:03:40
Done.
| |
| 467 * the current zone is allowed to intercept and replace the error. | 600 * the current zone is allowed to intercept and replace the error. |
| 468 * | 601 * |
| 469 * When other libraries use intermediate controllers or completers, such | 602 * There is no guarantee that an error is only sent through [errorCallback] |
| 470 * calls may contain errors that have already been processed. | 603 * once. Libraries that use intermediate controllers or completers might |
| 604 * end up invoking [errorCallback] multiple times. | |
| 471 * | 605 * |
| 472 * Return `null` if no replacement is desired. | 606 * Returns `null` if no replacement is desired. Otherwise returns an instance |
| 473 * The original error is used unchanged in that case. | 607 * of [AsyncError] holding the new pair of error and stack trace. |
| 474 * Otherwise return an instance of [AsyncError] holding | 608 * |
| 475 * the new pair of error and stack trace. | 609 * Although not recommended, the returned instance may have its `error` member |
| 476 * If the [AsyncError.error] is `null`, it is replaced by a [NullThrownError]. | 610 * ([AsyncError.error]) be equal to `null` in which case the error should be |
| 611 * replaced by a [NullThrownError]. | |
| 612 * | |
| 613 * Custom zones may intercept this operation. | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:02
Maybe add:
Implementations of a new asynchronous p
floitsch
2016/07/01 04:03:38
Done.
| |
| 477 */ | 614 */ |
| 478 AsyncError errorCallback(Object error, StackTrace stackTrace); | 615 AsyncError errorCallback(Object error, StackTrace stackTrace); |
| 479 | 616 |
| 480 /** | 617 /** |
| 481 * Runs [f] asynchronously in this zone. | 618 * Runs [f] asynchronously in this zone. |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
f -> action, task or callback.
floitsch
2016/07/01 04:03:39
Done.
| |
| 619 * | |
| 620 * The global `scheduleMicrotask` delegates to the current zone's | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:01
(Ick. We need a scope override in DartDoc to be ab
floitsch
2016/07/01 04:03:40
Acknowledged.
| |
| 621 * [scheduleMicrotask]. The root zone's implementation interacts with the | |
| 622 * embedder to schedule the given callback as microtask. | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:02
embedder -> underlying system
("embedder" is not
floitsch
2016/07/01 04:03:38
Done.
| |
| 623 * | |
| 624 * Custom zones may intercept this operation (for example to wrap the given | |
| 625 * callback [f]). | |
| 482 */ | 626 */ |
| 483 void scheduleMicrotask(void f()); | 627 void scheduleMicrotask(void f()); |
| 484 | 628 |
| 485 /** | 629 /** |
| 486 * Creates a task, given a [create] function and a [specification]. | 630 * Creates a task, given a [create] function and a [specification]. |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
That's actually vacuous. It's a function named "cr
floitsch
2016/07/01 04:03:39
Partially incorporated. In particular I don't want
| |
| 487 * | 631 * |
| 488 * The [create] function is invoked with the [specification] as argument. It | 632 * By default, in the root zone, the [create] function is invoked with the |
| 489 * returns a task object which is used for all future interactions with the | 633 * [specification] as argument. It returns a task object which is used for all |
| 490 * zone. | 634 * future interactions with the zone. Generally, the object is a unique |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:02
with the zone -> between the zone and the task
Lasse Reichstein Nielsen
2016/06/22 14:32:02
-> The object is a unique instance representing th
floitsch
2016/07/01 04:03:39
Done.
floitsch
2016/07/01 04:03:40
Done.
| |
| 635 * instance that is also returned to whoever initiated the action. | |
| 636 * For example, the HTML library uses the returned [StreamSubscription] as | |
| 637 * task object, when users register an event listener. | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:01
remove comma
floitsch
2016/07/01 04:03:40
Done.
| |
| 491 * | 638 * |
| 492 * Custom zones may replace the [specification] with a different one, thus | 639 * Tasks are created when the program starts an operation that returns |
| 493 * modifying the task parameters. | 640 * through the event loop. For example, a timer or an HTTP request both |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
"return through the event loop" is a clever image,
floitsch
2016/07/01 04:03:39
Partially incorporated. Kept the 'return' in the n
| |
| 494 * | |
| 495 * Tasks are created when the program is starting an operation that returns | |
| 496 * through the event loop. For example, a timer or an http request both | |
| 497 * return through the event loop and are therefore tasks. | 641 * return through the event loop and are therefore tasks. |
| 498 * | 642 * |
| 499 * If the [create] function is not invoked (because a custom zone has | 643 * If the [create] function is not invoked (because a custom zone has |
| 500 * replaced or intercepted it), then the operation is *not* started. This | 644 * replaced or intercepted it), then the operation is *not* started. This |
| 501 * means that a custom zone can intercept tasks, like http requests. | 645 * means that a custom zone can intercept tasks, like HTTP requests. |
| 646 * | |
| 647 * A task goes through the following steps: | |
| 648 * - a user invokes a library function that should eventually return through | |
| 649 * the event loop (and not just as a microtask). | |
| 650 * - the library function creates a [TaskSpecification] that contains the | |
| 651 * necessary information to start the operation, and invokes | |
| 652 * `Zone.current.createTask` with the specification and a [create] closure. | |
| 653 * The closure, when invoked, uses the specification to start the operation | |
| 654 * (usually by interacting with the embedder, ar as a native extension), | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:02
embedder -> underlying system (everywhere)
ar ->
floitsch
2016/07/01 04:03:40
Done.
| |
| 655 * and returns a task object that identifies the running task. | |
| 656 * - custom zones handle the request and (unless completely intercepted and | |
| 657 * aborted), end up calling the root zone's [createTask] which runs the | |
| 658 * provided `create` closure (which may have been replaced at this point). | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:02
parens into comma. (too mmany parenthesized clause
floitsch
2016/07/01 04:03:40
Done.
| |
| 659 * - later, the asynchronous operation returns through the event loop. | |
| 660 * It invokes [Zone.runTask] on the zone the task should run on (which had | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:02
on the zone in which the task should run (and whic
floitsch
2016/07/01 04:03:39
Done.
| |
| 661 * been given to the create function). The [runTask] function receives the | |
| 662 * task object, a `run` function and an argument. As before, custom zones | |
| 663 * may intercept this call. Eventually (unless aborted), the `run` function | |
| 664 * is invoked, running Dart code that has been registered to run when the | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
too much "run".
Maybe:
Eventually the `run` funct
floitsch
2016/07/01 04:03:39
Shortened it. I don't want to use 'callback' since
| |
| 665 * task returns. This last step may happen multiple times for tasks that are | |
| 666 * not oneshot tasks (see [ZoneSpecification.isOneShot]. | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
missing end paren.
floitsch
2016/07/01 04:03:40
Done.
| |
| 667 * | |
| 668 * Custom zones may replace the [specification] with a different one, thus | |
| 669 * modifying the task parameters. | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:02
Add:
An operation that wishes to be an interceptab
floitsch
2016/07/01 04:03:38
Done.
| |
| 502 */ | 670 */ |
| 503 Object/*=T*/ createTask/*<T, S>*/( | 671 Object/*=T*/ createTask/*<T, S>*/( |
| 504 TaskCreate/*<T, S>*/ create, TaskSpecification/*=S*/ specification); | 672 TaskCreate/*<T, S>*/ create, TaskSpecification/*=S*/ specification); |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
I would expand function types when used for parame
floitsch
2016/07/01 04:03:40
Done.
| |
| 505 | 673 |
| 506 /** | 674 /** |
| 507 * Runs a task callback. | 675 * Runs a task callback. |
| 508 * | 676 * |
| 509 * This function is invoked, when an operation, started through [createTask], | 677 * This function is invoked, when an operation, started through [createTask], |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:01
remove comma before "when"
floitsch
2016/07/01 04:03:38
Done.
| |
| 510 * returns to Dart code. | 678 * returns to Dart code. |
| 511 * | 679 * |
| 512 * Generally, tasks schedule Dart code in the global event loop. As such, | 680 * Generally, tasks schedule Dart code in the global event loop. As such, |
| 513 * there is no return value, and [runTask] is a void function. | 681 * there is no return value, and [runTask] is a void function. |
| 514 * | 682 * |
| 515 * The [task] object must be the same as the one created with [createTask]. | 683 * The [task] object must be the same as the one created with [createTask]. |
| 516 * | 684 * |
| 517 * It is good practice, if task operations provide a meaningful [arg], so | 685 * It is good practice, if task operations provide a meaningful [arg], so |
| 518 * that custom zones can deal with it. They might want to log it, or | 686 * that custom zones can deal with it. They might want to log it, or |
| 519 * replace it. | 687 * replace it. |
| 688 * | |
| 689 * See [createTask]. | |
| 520 */ | 690 */ |
| 521 void runTask/*<T, A>*/( | 691 void runTask/*<T, A>*/( |
| 522 TaskRun/*<T, A>*/ run, Object/*=T*/ task, Object/*=A*/ arg); | 692 TaskRun/*<T, A>*/ run, Object/*=T*/ task, Object/*=A*/ arg); |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:01
arg->argument.
floitsch
2016/07/01 04:03:40
Done.
| |
| 523 | 693 |
| 524 /** | 694 /** |
| 525 * Creates a Timer where the callback is executed in this zone. | 695 * Creates a Timer where the callback is executed in this zone. |
| 526 */ | 696 */ |
| 527 @deprecated | 697 @deprecated |
| 528 Timer createTimer(Duration duration, void callback()); | 698 Timer createTimer(Duration duration, void callback()); |
| 529 | 699 |
| 530 /** | 700 /** |
| 531 * Creates a periodic Timer where the callback is executed in this zone. | 701 * Creates a periodic Timer where the callback is executed in this zone. |
| 532 */ | 702 */ |
| 533 @deprecated | 703 @deprecated |
| 534 Timer createPeriodicTimer(Duration period, void callback(Timer timer)); | 704 Timer createPeriodicTimer(Duration period, void callback(Timer timer)); |
| 535 | 705 |
| 536 /** | 706 /** |
| 537 * Prints the given [line]. | 707 * Prints the given [line]. |
| 708 * | |
| 709 * The global `print` function delegates to the current zone's [print] | |
| 710 * function which makes it possible to intercept the print function. | |
|
Lasse Reichstein Nielsen
2016/06/22 14:32:03
intercept the print function -> intercept printing
floitsch
2016/07/01 04:03:39
Done.
| |
| 711 * | |
| 712 * Example: | |
| 713 * ``` | |
| 714 * import 'dart:async'; | |
| 715 * | |
| 716 * main() { | |
| 717 * runZoned(() { | |
| 718 * // Ends up printing: "Intercepted: in zone". | |
| 719 * print("in zone"); | |
| 720 * }, zoneSpecification: new ZoneSpecification( | |
| 721 * print: (Zone self, ZoneDelegate parent, Zone zone, String line) { | |
| 722 * parent.print(zone, "Intercepted: $line"); | |
| 723 * })); | |
| 724 * } | |
| 725 * ``` | |
| 538 */ | 726 */ |
| 539 void print(String line); | 727 void print(String line); |
| 540 | 728 |
| 541 /** | 729 /** |
| 542 * Call to enter the Zone. | 730 * Call to enter the Zone. |
| 543 * | 731 * |
| 544 * The previous current zone is returned. | 732 * The previous current zone is returned. |
| 545 */ | 733 */ |
| 546 static Zone _enter(Zone zone) { | 734 static Zone _enter(Zone zone) { |
| 547 assert(zone != null); | 735 assert(zone != null); |
| (...skipping 955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1503 handleUncaughtError: errorHandler); | 1691 handleUncaughtError: errorHandler); |
| 1504 } | 1692 } |
| 1505 Zone zone = Zone.current.fork(specification: zoneSpecification, | 1693 Zone zone = Zone.current.fork(specification: zoneSpecification, |
| 1506 zoneValues: zoneValues); | 1694 zoneValues: zoneValues); |
| 1507 if (onError != null) { | 1695 if (onError != null) { |
| 1508 return zone.runGuarded(body); | 1696 return zone.runGuarded(body); |
| 1509 } else { | 1697 } else { |
| 1510 return zone.run(body); | 1698 return zone.run(body); |
| 1511 } | 1699 } |
| 1512 } | 1700 } |
| OLD | NEW |