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

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: Address comment. Created 4 years, 5 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
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 this.handleUncaughtError: null, 166 this.handleUncaughtError: null,
167 this.run: null, 167 this.run: null,
168 this.runUnary: null, 168 this.runUnary: null,
169 this.runBinary: null, 169 this.runBinary: null,
170 this.registerCallback: null, 170 this.registerCallback: null,
171 this.registerUnaryCallback: null, 171 this.registerUnaryCallback: null,
172 this.registerBinaryCallback: null, 172 this.registerBinaryCallback: null,
173 this.errorCallback: null, 173 this.errorCallback: null,
174 this.scheduleMicrotask: null, 174 this.scheduleMicrotask: null,
175 this.createTimer: null, 175 this.createTimer: null,
176 this.createPeriodicTimer: null, 176 this.createPeriodicTimer: null,
Lasse Reichstein Nielsen 2016/07/11 11:18:29 Did createTask disappear?
floitsch 2016/07/11 11:20:36 I moved the comments into the CLs that added them
177 this.print: null, 177 this.print: null,
178 this.fork: null 178 this.fork: null
179 }); 179 });
180 180
181 final HandleUncaughtErrorHandler handleUncaughtError; 181 final HandleUncaughtErrorHandler handleUncaughtError;
182 final RunHandler run; 182 final RunHandler run;
183 final RunUnaryHandler runUnary; 183 final RunUnaryHandler runUnary;
184 final RunBinaryHandler runBinary; 184 final RunBinaryHandler runBinary;
185 final RegisterCallbackHandler registerCallback; 185 final RegisterCallbackHandler registerCallback;
186 final RegisterUnaryCallbackHandler registerUnaryCallback; 186 final RegisterUnaryCallbackHandler registerUnaryCallback;
187 final RegisterBinaryCallbackHandler registerBinaryCallback; 187 final RegisterBinaryCallbackHandler registerBinaryCallback;
188 final ErrorCallbackHandler errorCallback; 188 final ErrorCallbackHandler errorCallback;
189 final ScheduleMicrotaskHandler scheduleMicrotask; 189 final ScheduleMicrotaskHandler scheduleMicrotask;
190 final CreateTimerHandler createTimer; 190 final CreateTimerHandler createTimer;
191 final CreatePeriodicTimerHandler createPeriodicTimer; 191 final CreatePeriodicTimerHandler createPeriodicTimer;
192 final PrintHandler print; 192 final PrintHandler print;
193 final ForkHandler fork; 193 final ForkHandler fork;
194 } 194 }
195 195
196 /** 196 /**
197 * This class wraps zones for delegation. 197 * An adapted view of the parent zone.
198 * 198 *
199 * When forwarding to parent zones one can't just invoke the parent zone's 199 * This class allows the implementation of a zone method to invoke methods on
200 * exposed functions (like [Zone.run]), but one needs to provide more 200 * the parent zone while retaining knowledge of the originating zone.
201 * information (like the zone the `run` was initiated). Zone callbacks thus 201 *
202 * receive more information including this [ZoneDelegate] class. When delegating 202 * Custom zones (created through [Zone.fork] or [runZoned]) can provide
203 * to the parent zone one should go through the given instance instead of 203 * implementations of most methods of zones. This is similar to overriding
204 * directly invoking the parent zone. 204 * methods on [Zone], except that this mechanism doesn't require subclassing.
205 *
206 * A custom zone function (provided through a [ZoneSpecification]) typically
207 * records or wraps its parameters and then delegates the operation to its
208 * parent zone using the provided [ZoneDelegate].
209 *
210 * While zones have access to their parent zone (through [Zone.parent]) it is
211 * recommended to call the methods on the provided parent delegate for two
212 * reasons:
213 * 1. the delegate methods take an additional `zone` argument which is the
214 * zone the action has been initiated in.
215 * 2. delegate calls are more efficient, since the implementation knows how
216 * to skip zones that would just delegate to their parents.
205 */ 217 */
206 abstract class ZoneDelegate { 218 abstract class ZoneDelegate {
207 /*=R*/ handleUncaughtError/*<R>*/( 219 /*=R*/ handleUncaughtError/*<R>*/(
208 Zone zone, error, StackTrace stackTrace); 220 Zone zone, error, StackTrace stackTrace);
209 /*=R*/ run/*<R>*/(Zone zone, /*=R*/ f()); 221 /*=R*/ run/*<R>*/(Zone zone, /*=R*/ f());
210 /*=R*/ runUnary/*<R, T>*/(Zone zone, /*=R*/ f(/*=T*/ arg), /*=T*/ arg); 222 /*=R*/ runUnary/*<R, T>*/(Zone zone, /*=R*/ f(/*=T*/ arg), /*=T*/ arg);
211 /*=R*/ runBinary/*<R, T1, T2>*/(Zone zone, 223 /*=R*/ runBinary/*<R, T1, T2>*/(Zone zone,
212 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2); 224 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2);
213 ZoneCallback/*<R>*/ registerCallback/*<R>*/(Zone zone, /*=R*/ f()); 225 ZoneCallback/*<R>*/ registerCallback/*<R>*/(Zone zone, /*=R*/ f());
214 ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/( 226 ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/(
215 Zone zone, /*=R*/ f(/*=T*/ arg)); 227 Zone zone, /*=R*/ f(/*=T*/ arg));
216 ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/( 228 ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/(
217 Zone zone, /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2)); 229 Zone zone, /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2));
218 AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace); 230 AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace);
219 void scheduleMicrotask(Zone zone, void f()); 231 void scheduleMicrotask(Zone zone, void f());
220 Timer createTimer(Zone zone, Duration duration, void f()); 232 Timer createTimer(Zone zone, Duration duration, void f());
221 Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)); 233 Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer));
222 void print(Zone zone, String line); 234 void print(Zone zone, String line);
223 Zone fork(Zone zone, ZoneSpecification specification, Map zoneValues); 235 Zone fork(Zone zone, ZoneSpecification specification, Map zoneValues);
224 } 236 }
225 237
226 /** 238 /**
227 * A Zone represents the asynchronous version of a dynamic extent. Asynchronous 239 * A zone represents an environment that remains stable across asynchronous
228 * callbacks are executed in the zone they have been queued in. For example, 240 * calls.
229 * the callback of a `future.then` is executed in the same zone as the one where 241 *
230 * the `then` was invoked. 242 * Code is always executed in the context of a zone, available as
243 * [Zone.current]. The initial `main` function runs in the context of the
244 * default zone ([Zone.ROOT]). Code can be run in a different zone using either
245 * [runZoned], to create a new zone, or [Zone.run] to run code in the context of
246 * an existing zone likely created using [Zone.fork].
247 *
248 * Developers can create a new zone that overrides some of the functionality of
249 * an existing zone. For example, custom zones can replace of modify the
250 * behavior of `print`, timers, microtasks or how uncaught errors are handled.
251 *
252 * The [Zone] class is not subclassable, but users can provide custom zones by
253 * forking an existing zone (usually [Zone.current]) with a [ZoneSpecification].
254 * This is similar to creating a new class that extends the base `Zone` class
255 * and that overrides some methods, except without actually creating a new
256 * class. Instead the overriding methods are provided as functions that
257 * explicitly take the equivalent of their own class, the "super" class and the
258 * `this` object as parameters.
259 *
260 * Asynchronous callbacks always run in the context of the zone where they were
261 * scheduled. This is implemented using two steps:
262 * 1. the callback is first registered using one of [registerCallback],
263 * [registerUnaryCallback], or [registerBinaryCallback]. This allows the zone
264 * to record that a callback exists and potentially modify it (by returning a
265 * different callback). The code doing the registration (e.g., `Future.then`)
266 * also remembers the current zone so that it can later run the callback in
267 * that zone.
268 * 2. At a later point the registered callback is run in the remembered zone.
269 *
270 * This is all handled internally by the platform code and most users don't need
271 * to worry about it. However, developers of new asynchronous operations,
272 * provided by the underlying system or through native extensions, must follow
273 * the protocol to be zone compatible.
274 *
275 * For convenience, zones provide [bindCallback] (and the corresponding
276 * [bindUnaryCallback] or [bindBinaryCallback]) to make it easier to respect the
277 * zone contract: these functions first invoke the corresponding `register`
278 * functions and then wrap the returned function so that it runs in the current
279 * zone when it is later asynchronously invoked.
231 */ 280 */
232 abstract class Zone { 281 abstract class Zone {
233 // Private constructor so that it is not possible instantiate a Zone class. 282 // Private constructor so that it is not possible instantiate a Zone class.
234 Zone._(); 283 Zone._();
235 284
236 /** The root zone that is implicitly created. */ 285 /**
286 * The root zone.
287 *
288 * All isolate entry functions (`main` or spawned functions) start running in
289 * the root zone (that is, [Zone.current] is identical to [Zone.ROOT] when the
290 * entry function is called). If no custom zone is created, the rest of the
291 * program always runs in the root zone.
292 *
293 * The root zone implements the default behavior of all zone operations.
294 * Many methods, like [registerCallback] do the bare minimum required of the
295 * function, and are only provided as a hook for custom zones. Others, like
296 * [scheduleMicrotask], interact with the underlying system to implement the
297 * desired behavior.
298 */
237 static const Zone ROOT = _ROOT_ZONE; 299 static const Zone ROOT = _ROOT_ZONE;
238 300
239 /** The currently running zone. */ 301 /** The currently running zone. */
240 static Zone _current = _ROOT_ZONE; 302 static Zone _current = _ROOT_ZONE;
241 303
304 /** The zone that is currently active. */
242 static Zone get current => _current; 305 static Zone get current => _current;
243 306
307 /**
308 * Handles uncaught asynchronous errors.
309 *
310 * There are two kind of asynchronous errors that are handled by this
311 * function:
312 * 1. Uncaught errors that were thrown in asynchronous callbacks, for example,
313 * a `throw` in the function passed to [Timer.run].
314 * 2. Asynchronous errors that are pushed through [Future] and [Stream]
315 * chains, but for which no child registered an error handler.
316 * Most asynchronous classes, like [Future] or [Stream] push errors to their
317 * listeners. Errors are propagated this way until either a listener handles
318 * the error (for example with [Future.catchError]), or no listener is
319 * available anymore. In the latter case, futures and streams invoke the
320 * zone's [handleUncaughtError].
321 *
322 * By default, when handled by the root zone, uncaught asynchronous errors are
323 * treated like uncaught synchronous exceptions.
324 */
244 /*=R*/ handleUncaughtError/*<R>*/(error, StackTrace stackTrace); 325 /*=R*/ handleUncaughtError/*<R>*/(error, StackTrace stackTrace);
245 326
246 /** 327 /**
247 * Returns the parent zone. 328 * The parent zone of the this zone.
248 * 329 *
249 * Returns `null` if `this` is the [ROOT] zone. 330 * Is `null` if `this` is the [ROOT] zone.
331 *
332 * Zones are created by [fork] on an existing zone, or by [runZoned] which
333 * forks the [current] zone. The new zone's parent zone is the zone it was
334 * forked from.
250 */ 335 */
251 Zone get parent; 336 Zone get parent;
252 337
253 /** 338 /**
254 * The error zone is the one that is responsible for dealing with uncaught 339 * The error zone is the one that is responsible for dealing with uncaught
255 * errors. 340 * errors.
256 * Errors are not allowed to cross between zones with different error-zones. 341 *
257 * 342 * This is the closest parent zone of this zone that provides a
258 * This is the closest parent or ancestor zone of this zone that has a custom
259 * [handleUncaughtError] method. 343 * [handleUncaughtError] method.
344 *
345 * Asynchronous errors never cross zone boundaries between zones with
346 * different error handlers.
347 *
348 * Example:
349 * ```
350 * import 'dart:async';
351 *
352 * main() {
353 * var future;
354 * runZoned(() {
355 * // The asynchronous error is caught by the custom zone which prints
356 * // 'asynchronous error'.
357 * future = new Future.error("asynchronous error");
358 * }, onError: (e) { print(e); }); // Creates a zone with an error handler.
359 * // The following `catchError` handler is never invoked, because the
360 * // custom zone created by the call to `runZoned` provides an
361 * // error handler.
362 * future.catchError((e) { throw "is never reached"; });
363 * }
364 * ```
365 *
366 * Note that errors cannot enter a child zone with a different error handler
367 * either:
368 * ```
369 * import 'dart:async';
370 *
371 * main() {
372 * runZoned(() {
373 * // The following asynchronous error is *not* caught by the `catchError`
374 * // in the nested zone, since errors are not to cross zone boundaries
375 * // with different error handlers.
376 * // Instead the error is handled by the current error handler,
377 * // printing "Caught by outer zone: asynchronous error".
378 * var future = new Future.error("asynchronous error");
379 * runZoned(() {
380 * future.catchError((e) { throw "is never reached"; });
381 * }, onError: (e) { throw "is never reached"; });
382 * }, onError: (e) { print("Caught by outer zone: $e"); });
383 * }
384 * ```
260 */ 385 */
261 Zone get errorZone; 386 Zone get errorZone;
262 387
263 /** 388 /**
264 * Returns true if `this` and [otherZone] are in the same error zone. 389 * Returns true if `this` and [otherZone] are in the same error zone.
265 * 390 *
266 * Two zones are in the same error zone if they inherit their 391 * Two zones are in the same error zone if they have the same [errorZone].
267 * [handleUncaughtError] callback from the same [errorZone].
268 */ 392 */
269 bool inSameErrorZone(Zone otherZone); 393 bool inSameErrorZone(Zone otherZone);
270 394
271 /** 395 /**
272 * Creates a new zone as a child of `this`. 396 * Creates a new zone as a child of `this`.
273 * 397 *
274 * The new zone will have behavior like the current zone, except where 398 * The new zone uses the closures in the given [specification] to override
275 * overridden by functions in [specification]. 399 * the current's zone behavior. All specification entries that are `null`
276 * 400 * inherit the behavior from the parent zone (`this`).
277 * The new zone will have the same stored values (accessed through 401 *
278 * `operator []`) as this zone, but updated with the keys and values 402 * The new zone inherits the stored values (accessed through [operator []])
279 * in [zoneValues]. If a key is in both this zone's values and in 403 * of this zone and updates them with values from [zoneValues], which either
280 * `zoneValues`, the new zone will use the value from `zoneValues``. 404 * adds new values or overrides existing ones.
281 */ 405 *
282 Zone fork({ ZoneSpecification specification, 406 * Note that the fork operation is interceptible. A zone can thus change
283 Map zoneValues }); 407 * the zone specification (or zone values), giving the forking zone full
284 408 * control over the child zone.
285 /** 409 */
286 * Executes the given function [f] in this zone. 410 Zone fork({ZoneSpecification specification,
287 */ 411 Map zoneValues});
288 /*=R*/ run/*<R>*/(/*=R*/ f()); 412
289 413 /**
290 /** 414 * Executes [action] in this zone.
291 * Executes the given callback [f] with argument [arg] in this zone. 415 *
292 */ 416 * By default (as implemented in the [ROOT] zone), runs [action]
293 /*=R*/ runUnary/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg); 417 * with [current] set to this zone.
294 418 *
295 /** 419 * If [action] throws, the synchronous exception is not caught by the zone's
296 * Executes the given callback [f] with argument [arg1] and [arg2] in this 420 * error handler. Use [runGuarded] to achieve that.
421 *
422 * Since the root zone is the only zone that can modify the value of
423 * [current], custom zones intercepting run should always delegate to their
424 * parent zone. They may take actions before and after the call.
425 */
426 /*=R*/ run/*<R>*/(/*=R*/ action());
427
428 /**
429 * Executes the given [action] with [argument] in this zone.
430 *
431 * As [run] except that [action] is called with one [argument] instead of
432 * none.
433 */
434 /*=R*/ runUnary/*<R, T>*/(/*=R*/ action(/*=T*/ argument), /*=T*/ argument);
435
436 /**
437 * Executes the given [action] with [argument1] and [argument2] in this
297 * zone. 438 * zone.
439 *
440 * As [run] except that [action] is called with two arguments instead of none.
298 */ 441 */
299 /*=R*/ runBinary/*<R, T1, T2>*/( 442 /*=R*/ runBinary/*<R, T1, T2>*/(
300 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2); 443 /*=R*/ action(/*=T1*/ argument1, /*=T2*/ argument2), /*=T1*/ argument1,
301 444 /*=T2*/ argument2);
302 /** 445
303 * Executes the given function [f] in this zone. 446 /**
304 * 447 * Executes the given [action] in this zone and catches synchronous
305 * Same as [run] but catches uncaught errors and gives them to 448 * errors.
306 * [handleUncaughtError]. 449 *
307 */ 450 * This function is equivalent to:
308 /*=R*/ runGuarded/*<R>*/(/*=R*/ f()); 451 * ```
309 452 * try {
310 /** 453 * return this.run(action);
311 * Executes the given callback [f] in this zone. 454 * } catch (e, s) {
312 * 455 * return this.handleUncaughtError(e, s);
313 * Same as [runUnary] but catches uncaught errors and gives them to 456 * }
314 * [handleUncaughtError]. 457 * ```
315 */ 458 *
316 /*=R*/ runUnaryGuarded/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg); 459 * See [run].
317 460 */
318 /** 461 /*=R*/ runGuarded/*<R>*/(/*=R*/ action());
319 * Executes the given callback [f] in this zone. 462
320 * 463 /**
321 * Same as [runBinary] but catches uncaught errors and gives them to 464 * Executes the given [action] with [argument] in this zone and
322 * [handleUncaughtError]. 465 * catches synchronous errors.
466 *
467 * See [runGuarded].
468 */
469 /*=R*/ runUnaryGuarded/*<R, T>*/(/*=R*/ action(/*=T*/ argument),
470 /*=T*/ argument);
471
472 /**
473 * Executes the given [action] with [argument1] and [argument2] in this
474 * zone and catches synchronous errors.
475 *
476 * See [runGuarded].
323 */ 477 */
324 /*=R*/ runBinaryGuarded/*<R, T1, T2>*/( 478 /*=R*/ runBinaryGuarded/*<R, T1, T2>*/(
325 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2); 479 /*=R*/ action(/*=T1*/ argument1, /*=T2*/ argument2), /*=T1*/ argument1,
480 /*=T2*/ argument2);
326 481
327 /** 482 /**
328 * Registers the given callback in this zone. 483 * Registers the given callback in this zone.
329 * 484 *
330 * It is good practice to register asynchronous or delayed callbacks before 485 * When implementing an asynchronous primitive that uses callbacks, the
331 * invoking [run]. This gives the zone a chance to wrap the callback and 486 * callback must be registered using [registerCallback] at the point where the
332 * to store information with the callback. For example, a zone may decide 487 * user provides the callback. This allows zones to record other information
488 * that they need at the same time, perhaps even wrapping the callback, so
489 * that the callback is prepared when it is later run in the same zones
490 * (using [run]). For example, a zone may decide
333 * to store the stack trace (at the time of the registration) with the 491 * to store the stack trace (at the time of the registration) with the
334 * callback. 492 * callback.
335 * 493 *
336 * Returns a potentially new callback that should be used in place of the 494 * Returns the callback that should be used in place of the provided
337 * given [callback]. 495 * [callback]. Frequently zones simply return the original callback.
496 *
497 * Custom zones may intercept this operation. The default implementation in
498 * [Zone.ROOT] returns the original callback unchanged.
338 */ 499 */
339 ZoneCallback/*<R>*/ registerCallback/*<R>*/(/*=R*/ callback()); 500 ZoneCallback/*<R>*/ registerCallback/*<R>*/(/*=R*/ callback());
340 501
341 /** 502 /**
342 * Registers the given callback in this zone. 503 * Registers the given callback in this zone.
343 * 504 *
344 * Similar to [registerCallback] but with a unary callback. 505 * Similar to [registerCallback] but with a unary callback.
345 */ 506 */
346 ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/( 507 ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/(
347 /*=R*/ callback(/*=T*/ arg)); 508 /*=R*/ callback(/*=T*/ arg));
348 509
349 /** 510 /**
350 * Registers the given callback in this zone. 511 * Registers the given callback in this zone.
351 * 512 *
352 * Similar to [registerCallback] but with a unary callback. 513 * Similar to [registerCallback] but with a unary callback.
353 */ 514 */
354 ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/( 515 ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/(
355 /*=R*/ callback(/*=T1*/ arg1, /*=T2*/ arg2)); 516 /*=R*/ callback(/*=T1*/ arg1, /*=T2*/ arg2));
356 517
357 /** 518 /**
358 * Equivalent to: 519 * Equivalent to:
359 * 520 *
360 * ZoneCallback registered = registerCallback(f); 521 * ZoneCallback registered = this.registerCallback(action);
361 * if (runGuarded) return () => this.runGuarded(registered); 522 * if (runGuarded) return () => this.runGuarded(registered);
362 * return () => this.run(registered); 523 * return () => this.run(registered);
363 * 524 *
364 */ 525 */
365 ZoneCallback/*<R>*/ bindCallback/*<R>*/( 526 ZoneCallback/*<R>*/ bindCallback/*<R>*/(
366 /*=R*/ f(), { bool runGuarded: true }); 527 /*=R*/ action(), { bool runGuarded: true });
367 528
368 /** 529 /**
369 * Equivalent to: 530 * Equivalent to:
370 * 531 *
371 * ZoneCallback registered = registerUnaryCallback(f); 532 * ZoneCallback registered = this.registerUnaryCallback(action);
372 * if (runGuarded) return (arg) => this.runUnaryGuarded(registered, arg); 533 * if (runGuarded) return (arg) => this.runUnaryGuarded(registered, arg);
373 * return (arg) => thin.runUnary(registered, arg); 534 * return (arg) => thin.runUnary(registered, arg);
374 */ 535 */
375 ZoneUnaryCallback/*<R, T>*/ bindUnaryCallback/*<R, T>*/( 536 ZoneUnaryCallback/*<R, T>*/ bindUnaryCallback/*<R, T>*/(
376 /*=R*/ f(/*=T*/ arg), { bool runGuarded: true }); 537 /*=R*/ action(/*=T*/ argument), { bool runGuarded: true });
377 538
378 /** 539 /**
379 * Equivalent to: 540 * Equivalent to:
380 * 541 *
381 * ZoneCallback registered = registerBinaryCallback(f); 542 * ZoneCallback registered = registerBinaryCallback(action);
382 * if (runGuarded) { 543 * if (runGuarded) {
383 * return (arg1, arg2) => this.runBinaryGuarded(registered, arg); 544 * return (arg1, arg2) => this.runBinaryGuarded(registered, arg);
384 * } 545 * }
385 * return (arg1, arg2) => thin.runBinary(registered, arg1, arg2); 546 * return (arg1, arg2) => thin.runBinary(registered, arg1, arg2);
386 */ 547 */
387 ZoneBinaryCallback/*<R, T1, T2>*/ bindBinaryCallback/*<R, T1, T2>*/( 548 ZoneBinaryCallback/*<R, T1, T2>*/ bindBinaryCallback/*<R, T1, T2>*/(
388 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), { bool runGuarded: true }); 549 /*=R*/ action(/*=T1*/ argument1, /*=T2*/ argument2),
550 { bool runGuarded: true });
389 551
390 /** 552 /**
391 * Intercepts errors when added programmatically to a `Future` or `Stream`. 553 * Intercepts errors when added programatically to a `Future` or `Stream`.
392 * 554 *
393 * When caling [Completer.completeError], [Stream.addError], 555 * When calling [Completer.completeError], [Stream.addError],
394 * or [Future] constructors that take an error or a callback that may throw, 556 * or some [Future] constructors, the current zone is allowed to intercept
395 * the current zone is allowed to intercept and replace the error. 557 * and replace the error.
396 * 558 *
397 * When other libraries use intermediate controllers or completers, such 559 * Future constructors invoke this function when the error is received
398 * calls may contain errors that have already been processed. 560 * directly, for example with [Future.error], or when the error is caught
561 * synchronously, for example with [Future.sync].
399 * 562 *
400 * Return `null` if no replacement is desired. 563 * There is no guarantee that an error is only sent through [errorCallback]
401 * The original error is used unchanged in that case. 564 * once. Libraries that use intermediate controllers or completers might
402 * Otherwise return an instance of [AsyncError] holding 565 * end up invoking [errorCallback] multiple times.
403 * the new pair of error and stack trace. 566 *
404 * If the [AsyncError.error] is `null`, it is replaced by a [NullThrownError]. 567 * Returns `null` if no replacement is desired. Otherwise returns an instance
568 * of [AsyncError] holding the new pair of error and stack trace.
569 *
570 * Although not recommended, the returned instance may have its `error` member
571 * ([AsyncError.error]) be equal to `null` in which case the error should be
572 * replaced by a [NullThrownError].
573 *
574 * Custom zones may intercept this operation.
575 *
576 * Implementations of a new asynchronous primitive that converts synchronous
577 * errors to asynchronous errors rarely need to invoke [errorCallback], since
578 * errors are usually reported through future completers or stream
579 * controllers.
405 */ 580 */
406 AsyncError errorCallback(Object error, StackTrace stackTrace); 581 AsyncError errorCallback(Object error, StackTrace stackTrace);
407 582
408 /** 583 /**
409 * Runs [f] asynchronously in this zone. 584 * Runs [action] asynchronously in this zone.
585 *
586 * The global `scheduleMicrotask` delegates to the current zone's
587 * [scheduleMicrotask]. The root zone's implementation interacts with the
588 * underlying system to schedule the given callback as a microtask.
589 *
590 * Custom zones may intercept this operation (for example to wrap the given
591 * callback [action]).
410 */ 592 */
411 void scheduleMicrotask(void f()); 593 void scheduleMicrotask(void action());
412 594
413 /** 595 /**
414 * Creates a Timer where the callback is executed in this zone. 596 * Creates a Timer where the callback is executed in this zone.
415 */ 597 */
416 Timer createTimer(Duration duration, void callback()); 598 Timer createTimer(Duration duration, void callback());
417 599
418 /** 600 /**
419 * Creates a periodic Timer where the callback is executed in this zone. 601 * Creates a periodic Timer where the callback is executed in this zone.
420 */ 602 */
421 Timer createPeriodicTimer(Duration period, void callback(Timer timer)); 603 Timer createPeriodicTimer(Duration period, void callback(Timer timer));
422 604
423 /** 605 /**
424 * Prints the given [line]. 606 * Prints the given [line].
607 *
608 * The global `print` function delegates to the current zone's [print]
609 * function which makes it possible to intercept printing.
610 *
611 * Example:
612 * ```
613 * import 'dart:async';
614 *
615 * main() {
616 * runZoned(() {
617 * // Ends up printing: "Intercepted: in zone".
618 * print("in zone");
619 * }, zoneSpecification: new ZoneSpecification(
620 * print: (Zone self, ZoneDelegate parent, Zone zone, String line) {
621 * parent.print(zone, "Intercepted: $line");
622 * }));
623 * }
624 * ```
425 */ 625 */
426 void print(String line); 626 void print(String line);
427 627
428 /** 628 /**
429 * Call to enter the Zone. 629 * Call to enter the Zone.
430 * 630 *
431 * The previous current zone is returned. 631 * The previous current zone is returned.
432 */ 632 */
433 static Zone _enter(Zone zone) { 633 static Zone _enter(Zone zone) {
434 assert(zone != null); 634 assert(zone != null);
(...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after
1296 handleUncaughtError: errorHandler); 1496 handleUncaughtError: errorHandler);
1297 } 1497 }
1298 Zone zone = Zone.current.fork(specification: zoneSpecification, 1498 Zone zone = Zone.current.fork(specification: zoneSpecification,
1299 zoneValues: zoneValues); 1499 zoneValues: zoneValues);
1300 if (onError != null) { 1500 if (onError != null) {
1301 return zone.runGuarded(body); 1501 return zone.runGuarded(body);
1302 } else { 1502 } else {
1303 return zone.run(body); 1503 return zone.run(body);
1304 } 1504 }
1305 } 1505 }
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