在DART中,有没有办法把S在Zone米内创造的Future英尺都捕捉到?

目前,我被迫手动将它们全部捕获,但这似乎很容易忘记这样做.因此,如果可能的话,我想将其自动化.

在下面的示例代码中,我希望捕获someAsyncWork,这样就可以在Main runPluginCode运行后等待它.

import 'dart:async';

Future<void> main() async {
  print('Run plugin code');
  await runZoned(
    () async {
      runPluginCode();

      final tasks = Zone.current['tasks'] as List<Future>;

      await Future.wait(tasks);
    },
    zoneValues: {
      'taskId': 123,
      'tasks': <Future>[],
    },
  );
  print('Exit plugin code');
}

void runPluginCode() {
  // External QuickJS script that only has sync API methods
  // but they may call into async functions that need to be awaited before
  // the plugin code ends
  someTask();
}

void someTask() {
  print('performing task');
  // I don't want manually do this everywhere
  // final tasks = Zone.current['tasks'] as List<Future>;
  // tasks.add(someAsyncWork());
  someAsyncWork();
}

Future<void> someAsyncWork() async {
  await Future.delayed(const Duration(milliseconds: 200));
  final taskId = Zone.current['taskId'] as int;
  print('async work completed for task $taskId did I complete inside the plugin code???');
}

我相信这应该是可能的,当使用自定义ZoneSpecification

我试过了,但一点运气都没有.

    zoneSpecification: ZoneSpecification(
      run: <R>(self, parent, zone, f) {
        final task = parent.run(zone, f);
        if (task is Future) {
          (zone['tasks'] as List<Future>).add(task);
        }
        return task;
      },
      runUnary: <R, T>(self, parent, zone, f, arg) {
        final task = parent.runUnary(zone, f, arg);
        if (task is Future) {
          (zone['tasks'] as List<Future>).add(task);
        }
        return task;
      },
      runBinary: <R, T1, T2>(self, parent, zone, f, arg1, arg2) {
        final task = parent.runBinary(zone, f, arg1, arg2);
        if (task is Future) {
          (zone['tasks'] as List<Future>).add(task);
        }
        return task;
      },
    )

推荐答案

不是的.没有办法捕获在区域内创建的所有期货或任何期货.

与期货相比,区域是一个更低层次的抽象.期货是建立在区域之上的,因此区域对期货或溪流一无所知.

你可以对任何人在future 拨打then做出回应,因为这会呼叫zone.registerUnaryCallback,但创造future 是一个简单的操作,不会进行任何与区域相关的操作.它捕获当前区域(它确实不需要这样做),但仅此而已.

如果您想确保区域内的所有计算都已完成,则...嗯,你可能不能,但你可以更亲近一些:

  • 注意到每隔Zone.createTimerZone.createPeriodicTimerZone.scheduleMicrotask.然后您就可以知道是否有任何待处理的问题.(你需要知道这一点,才能知道这个区域已经"完成",而不仅仅是知道是否有未完成的期货.)
  • 注意每registerCallback个(以及..Unary....Binary..),知道有some个代码预计(可能)在该区域被调用.问题是,并不是所有这些都会运行,例如,future.then(handleValue, onError: handleError)只会调用handleValuehandleError中的一个,但它会同时注册这两个.然后用这些信息做something次.

通常不可能知道一个区域是否会再次进行计算,直到该区域被垃圾收集. 有人可能将区域存储在全局变量中,以便稍后调用storedZone.run(() { any code here });

Dart相关问答推荐

具有级联省道的三元算子的奇异行为

NetworkImage 正在缓存旧图像

在Dart中进行系统调用?

Dart 包对 git repo 子目录的依赖

Flutter tabview刷新问题

在polymer和dart中将内容标签渲染为模板的一部分

如何在 Dart 中创建一个空 Set

如何在 Flutter/dart 中获取一周中特定日期的日期?

如何删除ios上的overscroll?

不要将 PageView 居中 - Flutter

Flutter Null 安全迁移说Package doesn't exist

Flutter中图像纵横比的变化

如何判断一个字符串是否可以是 json.decode

如何在Flatter中设置特定容器中所有文本的 colored颜色 ?

是否有必要为Flatter安装Android Studio,或者可以用什么替代Android Studio?

如何从 ExpansionTile 的标题中删除默认填充

Flutter 中 ListView.builder 中的反向列表

在 Dart 中切换失败

如何在 base64 中编码 Dart 字符串?

有没有办法取消dartfuture ?