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);

因为我需要网络工作者是同步的——换句话说,给出一个返回值并且在你完成之前不要返回。

编辑1:

网络工作者正在使用 openDatabaseSync 事务对本地数据库进行插入/选择。

编辑2:

看来我的问题是 Cocoa Touch 而不是 JavaScript。 这是某人在 StackOverflow 上发布的一个聪明的 hack 。

编辑3:

这是一个更好的技巧

4

2 回答 2

5

Web Worker 的重点是在不阻塞 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),但即使编写同步包装器也不起作用(感谢评论者):

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);
}

编辑:“为什么你不能像这样同步工人”

onmessage处理程序将永远不会被调用,因为 JavaScript VM 一次只能调用一个函数并且该syncMe函数尚未退出。(抱歉造成混淆

于 2013-03-20T19:29:05.027 回答