 Chromium Code Reviews
 Chromium Code Reviews Issue 2082553003:
  More documentation for zones.  (Closed) 
  Base URL: https://github.com/dart-lang/sdk.git@master
    
  
    Issue 2082553003:
  More documentation for zones.  (Closed) 
  Base URL: https://github.com/dart-lang/sdk.git@master| OLD | NEW | 
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a | 
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. | 
| 4 | 4 | 
| 5 part of dart.async; | 5 part of dart.async; | 
| 6 | 6 | 
| 7 typedef R ZoneCallback<R>(); | 7 typedef R ZoneCallback<R>(); | 
| 8 typedef R ZoneUnaryCallback<R, T>(T arg); | 8 typedef R ZoneUnaryCallback<R, T>(T arg); | 
| 9 typedef R ZoneBinaryCallback<R, T1, T2>(T1 arg1, T2 arg2); | 9 typedef R ZoneBinaryCallback<R, T1, T2>(T1 arg1, T2 arg2); | 
| 10 | 10 | 
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 } | 
| OLD | NEW |