4

今、私はこれを持っています、そしてそれは動作します:

var myWebWorker = new Worker('myWebWorker.js');
myWebWorker.onmessage = function (myEvent) {
    $('#Print').append('Return value: ' + myEvent.data + "<br>");
};
myWebWorker.postMessage(2);

私の質問は: 代わりにこれを行うことはできますか?

var result = myWebWorker.postMessage(2);

Web ワーカーを同期させる必要があるためです。つまり、戻り値を指定し、終了するまで戻りません。

編集1:

Web ワーカーは、openDatabaseSync トランザクションを使用して、ローカル データベースへの挿入/選択を行っています。

編集2:

私の問題は、JavaScript ではなく Cocoa Touch にあるようです。 これは、誰かが StackOverflow に投稿した巧妙なハックです。

編集3:

これはより良いハックです。

4

2 に答える 2

5

Web ワーカーのポイントは、UI をブロックせずにタスクを委任することです。同期することはできません。

タスクを同期させる必要はないかもしれませんが、JavaScript アプリケーションや本格的な GUI アプリケーションを同期操作だけで設計できないのと同じように、イベントや非同期タスクを中心にコードを設計する必要があります。

于 2013-03-20T19:08:18.207 に答える
4

既に述べたように、ワーカーを同期的に呼び出すことはできません。ワーカーがメッセージを返すのを待機するラッパーを作成することもできますが、呼び出し元のコードでワーカーのコードを直接実行するのと同じ効果があります。ワーカー コードが実行されている間、呼び出し元はブロックされます。

ワーカーを使用する必要がある場合:

CPU1  CPU2    Explanation
 A            # Main script starts (in one Thread/CPU)
 |            # still runs...
 |---->B      # Offload some heavy work to Worker B (to another Thread/CPU)
 |     |      # A can do other stuff while B does some heavy work that would block A
 |<----B      # B is ready and posts the result to A
 |            # A is interrupted only shortly by B's message
 V

これで物事が明確になることを願っています。

このコードを追加するのをためらっています (つまり、Worker を同期的に呼び出す必要があることを再考してください) が、同期ラッパーを記述しても機能しません (コメント者への Thx ):

function syncMe(){
    var w = new Worker('myWebWorker.js');
    var data = null, ready = false;
    w.onmessage = function (e) {
        ready = true;
        data = e.data;
    };         
    w.postMessage(2)
    while(!ready){ /* block this thread forever, since `ready` is never changed */ }
    console.log(data);
}

編集:「このようにワーカーを同期できない理由」

JavaScript VM は一度に 1 つのonmessage関数しか呼び出すことができず、syncMe関数がまだ終了していないため、ハンドラーが呼び出されることはありません。(混乱してすみません

于 2013-03-20T19:29:05.027 に答える