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 |