runZonedGuarded<R> 函数

  1. @Since("2.8")
R? runZonedGuarded<R>(
  1. R body(),
  2. void onError(
    1. Object error,
    2. StackTrace stack
    ), {
  3. Map<Object?, Object?>? zoneValues,
  4. ZoneSpecification? zoneSpecification,
})

在其自身的错误区域内运行 body

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

onError 函数用于 同时 通过在 zoneSpecification 中重写 ZoneSpecification.handleUncaughtError 来处理异步错误,如果有的话,以及处理由 body 调用同步抛出的错误。

如果在 body 中同步发生错误,则在 onError 处理器中抛出会使得对 runZonedGuarded 的调用抛出该错误,否则对 runZonedGuarded 的调用将返回 null

创建的区域始终是 错误区域。异步错误永远不会跨越具有不同 Zone.errorZone 的区域之间的区域边界。该行为的一个后果是,从属于不同错误区域的区域使用时,创建区域中完成的错误似乎永远不会完成。在无法访问错误的区域内多次尝试使用该 future 将会导致在它原始的错误区域中再次报告错误。

实现

@Since("2.8")
R? runZonedGuarded<R>(R body(), void onError(Object error, StackTrace stack),
    {Map<Object?, Object?>? zoneValues, ZoneSpecification? zoneSpecification}) {
  checkNotNullable(body, "body");
  checkNotNullable(onError, "onError");
  _Zone parentZone = Zone._current;
  HandleUncaughtErrorHandler errorHandler = (Zone self, ZoneDelegate parent,
      Zone zone, Object error, StackTrace stackTrace) {
    try {
      parentZone.runBinary(onError, error, stackTrace);
    } catch (e, s) {
      if (identical(e, error)) {
        parent.handleUncaughtError(zone, error, stackTrace);
      } else {
        parent.handleUncaughtError(zone, e, s);
      }
    }
  };
  if (zoneSpecification == null) {
    zoneSpecification = ZoneSpecification(handleUncaughtError: errorHandler);
  } else {
    zoneSpecification = ZoneSpecification.from(zoneSpecification,
        handleUncaughtError: errorHandler);
  }
  try {
    return _runZoned<R>(body, zoneValues, zoneSpecification);
  } catch (error, stackTrace) {
    onError(error, stackTrace);
  }
  return null;
}