61

postMessage関数を介してオブジェクトをWebワーカーに渡そうとしています。
このオブジェクトは、キャンバスやその他の物に自分自身を描くためのいくつかの機能を備えた正方形です。Webワーカーは、このオブジェクトの配列を返す必要があります。
問題は、このオブジェクトを使用してpostMessage関数を呼び出すと、次のエラーが発生することです。

Uncaught Error: DATA_CLONE_ERR: DOM Exception 25

これは、オブジェクトをワーカーに送信することと、その逆の両方で取得します。
エラーは、JavaScriptがオブジェクトをシリアル化する必要があるためだと思いますが、オブジェクトには関数が組み込まれているため、シリアル化できません。

誰かが同じような問題を抱えたことはありますか?これに対する回避策を知っていますか?
前もって感謝します。

4

8 に答える 8

54

あなたが言及したエラーがスローされた理由はいくつかあります。理由はここにリストされています

オブジェクトが Web ワーカーに送信されると、オブジェクトはシリアル化され、オブジェクトがシリアル化可能なオブジェクトである場合は、後で Web ワーカーで逆シリアル化されます。

これは、Web Worker に送信するオブジェクトのメソッドが Web Worker に渡せるものではないことを意味し (発生したエラーを引き起こします)、オブジェクトに必要なメソッド/関数を提供する必要があります。環境の Web ワーカー側で、それらが Web ワーカーに渡されるオブジェクトの一部でないことを確認してください。

于 2011-10-09T19:03:47.770 に答える
13

ご想像のとおり、機能を持つオブジェクトは投稿できません。同じことが再帰参照を持つオブジェクトにも当てはまりますが、これは最近一部のブラウザーで変更されました。投稿ごとに手動でコストのかかる冗長なシリアル化を行うリスクを冒す代わりに、スクリプトの最初でテストを実行して、データの送受信に使用する関数を決定できます。

私は同じ問題を抱えており、ほとんどすべてのコードをワーカーに移動し、メインスレッドにレンダラー (2d コンテキストレンダラーをラップ) を保持することで解決しました。ワーカーでは、キャンバス用のさまざまな描画呼び出しを (型指定された) 配列の数字だけにシリアル化します。次に、この配列がメイン スレッドにポストされます。

たとえば、画像を描画するdrawImage()場合は、ワーカー内のワーカー レンダラー インスタンスでメソッドを呼び出します。[13,1,50,40]呼び出しは、描画メソッドの列挙型、画像の一意の ID、およびその xy 座標に対応するようなものに変換されます。複数の呼び出しがバッファリングされ、同じ配列に入れられます。更新ループの最後に、配列がメイン スレッドにポストされます。受信側のメイン レンダラー インスタンスは配列を解析し、適切な描画呼び出しを実行します。

于 2012-01-18T23:58:24.997 に答える
9

最近、Web ワーカーを使用しているときに、この同じ問題に遭遇しました。ワーカーに渡したものはすべて、そのすべてのプロパティを保持していましたが、不思議なことにすべてのメソッドが失われました。

Web ワーカー スクリプト自体でメソッドを定義する必要があります。回避策の 1 つはimportScripts、クラスを定義し、__proto__受け取ったもののプロパティを手動で設定することです。私の場合、 (そう、私は 2048 で作業していました) でgrid定義されたオブジェクトを渡したかったので、次のようにしました。grid.js

importScripts('grid.js')

onMessage = function(e) {
  e.data.grid.__proto__ = Grid.prototype;
  ...
}
于 2014-04-20T10:27:19.777 に答える
5

オブジェクトと Webworker の本当の問題は、そのオブジェクトのメソッドにあります。オブジェクトは、メソッドだけを持つべきではありません。

元:

var myClass = function(){
    this.a = 5;
    this.myMethod = function(){}
}
var notParseableObject = new myClass();


var myClass2 = function(){
    this.a = 5;
}
var parseableObject = new myClass2();

1 つ目は postMessage では機能せず (上記のエラー メッセージが表示されます)、2 つ目は機能します。

于 2012-09-04T13:34:08.127 に答える
2

vkThreadプラグインを見てください

http://www.eslinstructor.net/vkthread/

コンテキストを持つ関数 ( object's method ) を含む関数をワーカーに渡すことができます。また、依存関係のある関数、無名関数、およびラムダを渡すこともできます。

--ヴァディム

于 2013-07-30T15:06:59.180 に答える