runZoned<R> 函数

R runZoned<R>(
  1. R body(), {
  2. Map<Object?, Object?>? zoneValues,
  3. ZoneSpecification? zoneSpecification,
  4. @弃用("请使用 runZonedGuarded 代替") Function? onError,
})

在其自己的区域中运行 body

基于 zoneSpecificationzoneValues 使用 Zone.fork 创建一个新的区域,然后在其中运行 body 并返回结果。

示例用法

var secret = "arglebargle"; // Or a random generated string.
var result = runZoned(
    () async {
      await Future.delayed(Duration(seconds: 5), () {
        print("${Zone.current[#_secret]} glop glyf");
      });
    },
    zoneValues: {#_secret: secret},
    zoneSpecification:
        ZoneSpecification(print: (Zone self, parent, zone, String value) {
      if (value.contains(Zone.current[#_secret] as String)) {
        value = "--censored--";
      }
      parent.print(zone, value);
    }));
secret = ""; // Erase the evidence.
await result; // Wait for asynchronous computation to complete.

新区域拦截 print 并在私有符号 #_secret 下存储一个值。这个秘密可以从新的 Zone 对象中获取,它是 bodyZone.current,也是 print 处理函数的第一个、self 参数。

如果设置了 ZoneSpecification.handleUncaughtError,或者传递了弃用的 onError 回调,则创建的区域将是一个 错误区域。异步错误在具有不同 Zone.errorZone 的区域之间不会跨越区域边界。这种行为的一个后果是,在创建的区域中完成的 Future 似乎永远不会完成,当从属于不同错误区域的区域中使用时。在无法访问错误的区域中多次尝试使用该 future 会导致在它原始的错误区域中 再次 报错。

请使用 runZonedGuarded 代替弃用的 onError 参数。如果提供了 onError,此函数还尝试捕获和处理来自 body 的同步错误,但如果泛型参数 R 不可为 null,则可能仍然抛出错误并返回 null

实现

R runZoned<R>(R body(),
    {Map<Object?, Object?>? zoneValues,
    ZoneSpecification? zoneSpecification,
    @Deprecated("Use runZonedGuarded instead") Function? onError}) {
  checkNotNullable(body, "body");
  if (onError != null) {
    // TODO: Remove this when code have been migrated off using [onError].
    if (onError is! void Function(Object, StackTrace)) {
      if (onError is void Function(Object)) {
        var originalOnError = onError;
        onError = (Object error, StackTrace stack) => originalOnError(error);
      } else {
        throw ArgumentError.value(onError, "onError",
            "Must be Function(Object) or Function(Object, StackTrace)");
      }
    }
    return runZonedGuarded(body, onError,
        zoneSpecification: zoneSpecification, zoneValues: zoneValues) as R;
  }
  return _runZoned<R>(body, zoneValues, zoneSpecification);
}