从Web worker获取返回值

时间:2013-03-20 19:07:03

标签: javascript web-worker

现在,我已经有了这个,并且它有效:

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 worker同步 - 换句话说,给出一个返回值,并且在你完成之前也不会返回。

编辑1:

Web worker正在使用openDatabaseSync事务对本地数据库进行插入/选择。

编辑2:

我的问题似乎是Cocoa Touch,而不是JavaScript。 有人在StackOverflow上发布的Here's a clever hack

编辑3:

这是a better hack

2 个答案:

答案 0 :(得分:5)

Web工作者的目的是在不阻止UI的情况下委派任务。 他们不能同步。

您可能不需要需要任务同步,但您需要围绕事件和异步任务设计代码,就像您无法设计任何javascript应用程序或任何严重的GUI应用程序一样同步操作。

答案 1 :(得分:4)

如前所述,您无法同步呼叫工作人员。您可以编写一个等待worker返回消息的包装器,但这与在调用者的代码中直接执行worker的代码具有相同的效果。在工作人员代码运行时,调用者将被阻止。

何时应该使用工人:

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 to the commenters ):

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函数尚未退出。 (对不起混淆