web-dev-qa-db-ja.com

Webワーカーからの転送可能なオブジェクトの使用

私は現在、Webワーカーを作成するためのこのコードを持っています。

w = new Worker("webwork.js");
w.onmessage = function(event) { alert(event.data); }

そしてwebwork.js Webワーカーのコード:

self.onmessage = function(event) {
    //var ss=r;  //Causes error because of undefined
    var ss="";
    for(var currProp in event) {
        ss+=("event."+currProp+"="+event[currProp]+"\n");
    }
    postMessage(ss);
}

次のコードで128メガバイトのArrayBufferを転送したいと思います。

var r = new ArrayBuffer(1048576*128);
w.postMessage(0, [r]);

変数rを転送したはずですが、Webワーカー自体から変数にアクセスするにはどうすればよいですか。私が試してみました event.rrself.rおよびArrayBuffersの配列に2番目の関数引数を追加しようとするようなものですが、何も機能しません。

転送された変数にWebワーカーからどのようにアクセスできますか?

29
alt.126
PostMesage(aMessage, transferList)

transferListでは、aMessageに含まれる転送可能なオブジェクトを指定する必要があります。

var objData =
{
    str: "string",
    ab: new ArrayBuffer(100),
    i8: new Int8Array(200)
};
objWorker.postMessage(objData, [objData.ab, objData.i8.buffer]);

反対側:

self.onmessage = function(objEvent)
{
    var strText = objEvent.data.str;
    var objTypedArray = objEvent.data.ab;
    var objTypedArrayView = objEvent.data.i8;
}
37
CoolCmd

Sbrによる回答は機能しますが、ワーカーに送信される前にデータのコピーが作成されます。大量のデータの場合、処理が遅くなる可能性があります。
「転送可能なオブジェクト」を使用するには、実際にオブジェクトの所有権をWebワーカーとの間で転送します。これは、コピーが作成されない場所で参照渡しをするようなものです。それと通常の参照渡しの違いは、データを転送した側がデータにアクセスできなくなることです。

例のデータを送信する方法は次のとおりです。

w.postMessage(r,[r]);  // first arg is r, not 0 as in the question

そして、あなたがウェブワーカーでそれにアクセスする方法:

addEventListener('message', function(event) {
    var r = event.data;
});

私自身のアプリケーションでは、コピーのパフォーマンスを犠牲にすることなく、大きな型付きのFloat64ArrayをWebワーカーからメインスレッドに送信する必要がありました。多くの試行錯誤と検索が必要だったので、同様の問題に悩まされている人のために、ここにその例を含める必要があると考えました。
これはワーカー側で機能したコードです(arrは私のFloat64Arrayです):

self.postMessage(arr.buffer, [arr.buffer]);

私が持っている受信メインスレッドでは:

theWorker.addEventListener('message', function(ev) {
    var arr = new Float64Array(ev.data);  // just cast it to the desired type - no copy made
    // ...
});

これはChromeで機能しますが、この日付の時点では他のほとんどのブラウザーではない可能性があることに注意してください(まだ試していません)。

また、大きな配列に加えて他の情報を送信したい場合は、これを行うことができます:

self.postMessage({foo:"foo", bar:arr.buffer}, [arr.buffer]);

受信(この例ではメイン)スレッド:

theWorker.addEventListener('message', function(event) {
    var foo = event.data.foo;
    var arr = new Float64Array(event.data.bar);  // cast it to the desired type
    // ...
});
48
yanni

webワーカーを簡単に使用したい場合は、この小さなlibを試すことができます: [〜#〜] ww [〜#〜]

それが役に立てば幸い

0
Erol

W.postMessage([0、r])を試してください。転送可能なオブジェクトを使用するには、配列バッファーを配列の2番目の項目として渡す必要があります。 this を参照

0
Wyatt