【问题标题】:Dart: in browser webworker written in dart and used in dart2jsDart:在浏览器中用 dart 编写并在 dart2js 中使用的 webworker
【发布时间】:2015-02-11 19:11:54
【问题描述】:

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

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

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

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

谢谢。

【问题讨论】:

    标签: dart web-worker


    【解决方案1】:

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

    目前,您更有可能在 Dartium 中遇到问题,因为隔离区不会映射到工作人员。它们并行运行,但无权访问工作人员 API。这正在处理中。这也是你不能在 Dartium 中使用 spawn 的原因,以防止产生带有 dart:html 代码的东西,如果它尝试使用这些 API,就会中断。不幸的是,即使是像 print() 这样简单的东西现在也会抛出一个 Dartium 隔离。但据我所知,这一切都在部署中运行良好。

    【讨论】:

    • 只是为了确保您能确认以下内容是否适用于 Dartium 和生产环境:1) xmlhttp 在 main 2) 传输 responseText 以隔离 3) 解析(使用 dart:convert)到类/对象并处理该数据 4)完成后传输回主对象(如果需要,作为对象或作为序列化对象) - 这主要是我现在的用例。稍后我需要在工作人员上使用 lovefield,但它是 JS,所以我预计不会出现问题。
    • 是的。您需要使用发送/接收端口在它们之间传递数据,因此需要序列化。在 Dartium worker 中运行 JS 可能是个问题,但这是我们正在努力的一部分。
    • 这方面有更新吗?我们现在可以在 dart 1.16 中使用 Dartium 中的 Isolates 吗?
    【解决方案2】:

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

    这是 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 worker 的 web 应用程序,而不是常见的 webdev serve,我们需要使用 webdev serve -r。这表示一个发布版本,换句话说,使用 dart2js 而不是 dartdevc。

    如果您想查看整个工作示例,这里是 git repro:https://github.com/yuan-kuan/dog-raiser

    【讨论】:

      猜你喜欢
      • 2013-10-04
      • 2023-03-23
      • 2020-05-11
      • 2013-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-27
      • 1970-01-01
      相关资源
      最近更新 更多