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.dart
和 worker.dart
都需要位于 web/
文件夹中。他们共享相同的狗自定义包,该包位于 lib/
文件夹中。
现在,主要警告:为了 运行 这个 Web 应用程序在开发过程中正确地在浏览器中使用 Web Worker,而不是常见的 webdev serve
,我们需要使用 webdev serve -r
。表示发布版本,换句话说,使用dart2js而不是dartdevc。
如果您想查看整个工作示例,请查看 git 重现:https://github.com/yuan-kuan/dog-raiser
基本上我现在很困惑:设置非常简单 - 我想使用 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.dart
和 worker.dart
都需要位于 web/
文件夹中。他们共享相同的狗自定义包,该包位于 lib/
文件夹中。
现在,主要警告:为了 运行 这个 Web 应用程序在开发过程中正确地在浏览器中使用 Web Worker,而不是常见的 webdev serve
,我们需要使用 webdev serve -r
。表示发布版本,换句话说,使用dart2js而不是dartdevc。
如果您想查看整个工作示例,请查看 git 重现:https://github.com/yuan-kuan/dog-raiser