ES6 Web Worker的可转移自定义类 [英] Transferable custom classes with ES6 web workers

查看:298
本文介绍了ES6 Web Worker的可转移自定义类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Javascript ES6的浏览器中,我想使用"Transferable"界面将自定义类对象传输到Web Worker.这可能吗?我可以找到有关ArrayBuffer对象的文档,而不是自定义类对象的文档.

In Javascript ES6, in the browser, I want to transfer custom class objects to a web worker using the "Transferable" interface. Is this possible? I can find documentation about this for ArrayBuffer objects, but not for custom class objects.

这不是如何通过自定义类的副本是通过Web-Workers实例?,因为我的问题特别是关于Transferable接口.我想将自定义类实例传递给工作程序而不复制它.

This is not a duplicate of How to pass custom class instances through Web-Workers? since my question is specifically about the Transferable interface. I want to pass my custom class instance to the worker without copying it.

推荐答案

我已经以不同的方式几次解决了这个问题.抱歉,对于您所查询的特定版本的答案肯定是.

I already addressed this question a few times, in different ways. I'm sorry, but the answer to your particular version of this inquiry is definitely no.

有几个原因.

  1. 通常不将单个JavaScript对象分配在连续的内存块上(这至少使得理论上可以传输它们).
  2. 任何将普通对象/类转换为ArrayBuffer的代码实际上都只是现有结构化克隆算法的开销,
  1. Individual JavaScript objects are typically not allocated on continuous memory chunks (which would make it possible to transfer them in theory at least).
  2. Any code that converts normal object/class to a ArrayBuffer would really just be overhead over the existing structured clone algorithm, that does the job well.

你能做什么,

如果您真的想要,但我不确定是否应该这么做.

What you can do,

if you really want to which I'm not so sure you should.

想象一个这样的类:

class Vector2 {
    constructor(existing) {
        this._data = new Float64Array(2);
    }

    get x() {
      return this._data[0];
    }
    set x(x) {
      this._data[0] = x;
    }
    get y() {
      return this._data[1];
    }
    set y(y) {
      this._data[1] = y;
    }
}

它的属性存储在数组缓冲区中,您可以传输它.但这并没有太大用处,要使其正常工作,我们需要确保可以从接收到的数组缓冲区中构造它.可以肯定地做到这一点:

It's properties are stored in an array buffer and you can transfer it. But it's not much use yet, for it to work well, we need to make sure it can be constructed from received array buffer. That can be done for sure:

class Vector2 {
    constructor(existing) {
        if(existing instanceof ArrayBuffer) {
            this.load(existing);
        }
        else {
            this.init();
        }
    }
    /*
     * Loads from existing buffer
     * @param {ArrayBuffer} existing
    */
    load(existing) {
      this._data = existing;
      this.initProperties();
    }
    init() {
      // 16 bytes, 8 for each Float64
      this._data = new ArrayBuffer(16);
      this.initProperties();
    }
    initProperties() {
      this._coordsView = new Float64Array(this._data, 0, 2);
    }

    get x() {
      return this._coordsView[0];
    }
    set x(x) {
      this._coordsView[0] = x;
    }
    get y() {
      return this._coordsView[1];
    }
    set y(y) {
      this._coordsView[1] = y;
    }
}

现在,您甚至可以通过从子类传递更大的数组缓冲区来对其进行子类化,在该子类中,父级和子级属性都适合:

Now you can even subclass it, by passing larger array buffer from the subclass, where both parents and child's attributes will fit:

class Vector2Altitude extends Vector2 {
  constructor(existing) {
    super(existing instanceof ArrayBuffer ? existing : new ArrayBuffer(16 + 8));
    this._altitudeView = new Float64Array(this._data, 16, 1);
  }
  get altitude() {
    return this._altitudeView[0];
  }
  set altitude(alt) {
    this._altitudeView[0] = alt;
  }
}

一个简单的测试:

const test = new Vector2();
console.log(test.x, test.y);
const test2 = new Vector2Altitude();
test2.altitude = 1000;
console.log(test2.x, test2.y, test2.altitude, new Uint8Array(test2._data));

要真正使用它,您需要解决许多其他问题,并从根本上实现对复杂对象的内存分配.

To make some real use of it, you need to solve many other problems, and essentially implement your own memory allocation for complex objects.

这篇关于ES6 Web Worker的可转移自定义类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆