Dart:在浏览器中使用 dart 编写的 webworker,并在 dart2js 中使用

Dart: in browser webworker written in dart and used in dart2js

基本上我现在很困惑:设置非常简单 - 我想使用 dart 编写主应用程序和网络工作者部分 - 需要访问相同 APIs 常规的部分JS web worker 具有并且在部署时作为真正的 worker 运行(即编译为 js)。

据我所知,dart isolates 不是我想要的,因为当编译为 JS 时,它们作为主线程的一部分执行,即使它们不与主代码共享状态——这对我的用例来说是不可接受的.

此外,如果我理解正确的话,如果我要将 Worker API 与脚本 uri 一起使用,我将无法使用 dart 代码,但即使我可以,它也必须是一个完全独立的项目,并且不能成为我的一部分主要代码(就像隔离一样)。

在 Dart 的当前状态下,我的场景是否可行?一个关于如何使用 dart 中的 web worker 并在 dart 中编写 worker 代码以及访问 xmlhttprequest 的简化示例会很棒。我知道如果没有 serialization/deserialization 我可能无法传输对象,但这没关系。

谢谢。

dart2js 中的 Isolates 将被映射到 workers。您应该能够使用 spawn 或 spawnUri。所以那部分应该没问题。

目前,您在 Dartium 中开发时更有可能遇到问题,其中 isolates 不映射到 workers。他们 运行 并行,但无权访问 worker API。正在努力。这也是您不能在 Dartium 中使用 spawn 的原因,以防止使用 dart:html 代码生成某些东西,如果它尝试使用这些 API,这些代码将会中断。不幸的是,即使像 print() 这样简单的东西现在也会抛出 Dartium isolate。但据我所知,它在部署中运行良好。

我设法完成了这项工作,但有一个警告。

这是 main.dart 的样子

import 'dart:async';
import 'dart:html';

import 'package:excel_worker/dog.dart';

void main() {
  var w = Worker('worker/dog_raiser.dart.js');

  // Listen to Worker's postMessage().
  // dart.html convert the callback to a Stream.
  w.onMessage.listen((msg) {
    var dog = Dog(name: msg.data['name'], age: msg.data['age']);
    print('master took back ${dog.name} and she turns into ${dog.age}!');
  });

  // After one second, post a message to the Worker.
  new Timer(Duration(seconds:1), () {
    w.postMessage(Dog(name : 'Marley', age: 1));
  });
}

这是工作人员。

import 'package:js/js.dart';

import 'package:excel_worker/dog.dart';

@anonymous
@JS()
abstract class MessageEvent {
  external dynamic get data;
}

@JS('postMessage')
external void PostMessage(obj);

@JS('onmessage')
external void set onMessage(f);

void main() {
  print('Worker created');

  // 'allowInterop' is necessary to pass a function into js.
  onMessage = allowInterop((event) {
    var e = event as MessageEvent;
    var dog = e.data as Dog;
    print('worker: got ${dog.name} from master, raising it from ${dog.age}...');

    PostMessage(Dog(name : '${dog.name} 2.0', age: dog.age + 1));
  });
}

main.dartworker.dart 都需要位于 web/ 文件夹中。他们共享相同的狗自定义包,该包位于 lib/ 文件夹中。

现在,主要警告:为了 运行 这个 Web 应用程序在开发过程中正确地在浏览器中使用 Web Worker,而不是常见的 webdev serve,我们需要使用 webdev serve -r。表示发布版本,换句话说,使用dart2js而不是dartdevc。

如果您想查看整个工作示例,请查看 git 重现:https://github.com/yuan-kuan/dog-raiser