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

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

Issue 2082553003: More documentation for zones. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of dart.async; 5 part of dart.async;
6 6
7 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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698