【问题标题】:Getting a return value back from a web worker从网络工作者那里获取返回值
【发布时间】:2013-03-20 19:07:03
【问题描述】:

现在,我得到了这个,它可以工作:

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。 Here's a clever hack 有人在 StackOverflow 上发帖。

编辑 3:

这里是a better hack

【问题讨论】:

  • 为什么需要同步?您是否从 onmessage 回调中获取数据?
  • 是的,我从 onmessage 回调中正确获取了数据。但是编写这个应用程序的 Cocoa Touch 部分的人不知道如何去听它。也许 Cocoa touch 可以监听一些我可以使用 JavaScript 触发的东西,比如点击事件或其他东西。

标签: javascript web-worker


【解决方案1】:

网络工作者的重点是在不阻塞 UI 的情况下委派任务。 它们不能同步。

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

【讨论】:

  • 我有一台设备正在发出 JavaScript 命令并期待返回结果。我不认为它知道任何回调——它只是发出一个命令并期待一个结果,所以我所做的一切都必须是同步的。
  • 你的设备是什么?软件期望从 javascript 命令获得同步结果是非常奇怪的。如果您的任务必须是同步的(这很可能是错误的要求),您为什么要尝试使用 webworker ?
  • 一台 iPad。我不认为 Cocoa Touch 可以监听事件 - 可以吗?
  • 好吧,我不是 iOS 专家,但我从 Cocoa 应用程序调用 JavaScript 来更新本地数据库,然后期望 JavaScript 同步使用 Web Worker,因为这看起来很奇怪。您的问题可能有更简单的解决方案。
【解决方案2】:

如前所述,您不能同步调用工作程序。您可以编写一个等待工作人员返回消息的包装器,但这与直接在调用者的代码中执行工作人员的代码具有相同的效果。在工作代码运行期间,调用者将被阻塞。

什么时候应该使用工人:

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 函数尚未退出。 (抱歉给您带来了困扰

【讨论】:

  • while(!ready){ /* block this thread! */ } ?我认为你不应该建议这个。
  • @dystroy 我知道,我想我也明确表示我不应该这样做。但它很好地显示了主线程是如何被阻塞的。人们需要通过例子来学习。
  • 这行不通。 onmessage 回调将等到代码完成......它不会。
  • 是的,我认为这行不通。在尝试使用网络工作者之前,我已经尝试过,我认为 while(!ready) 循环可以防止 onmessage 被调用。
  • 也许我的问题与 Cocoa Touch 开发有关,而不是 JavaScript。
猜你喜欢
  • 2020-12-25
  • 1970-01-01
  • 1970-01-01
  • 2019-06-30
  • 1970-01-01
  • 1970-01-01
  • 2020-09-12
  • 1970-01-01
相关资源
最近更新 更多