HTML5从Worker调用全局函数

时间:2014-02-24 11:56:45

标签: javascript html5 web-worker

我在Utils.js中有一个名为“sendAndWaitCommand”的全局函数 当我尝试从Worker(名称'uploadToDevice.js')调用此函数时,工作程序崩溃。

  • 工人初始化

    var worker = new Worker('uploadToDevice.js');   
    worker.postMessage(SplitedFile);
    
  • 工人(uploadToDevice.js)

    self.addEventListener('message', function (e)   
    {   
      var SplitedFile = e.data;   
      sendAndWaitCommand(SplitedFile[0].substring(1));//crash here   
    
    }, false);   
    
  • Utils.js

     function sendAndWaitCommand(commandToSend)   
     {   
        ...//Some heavy stuff to do.  
     }  
    

有没有办法在没有工人崩溃的情况下调用全局函数? 如果没有,是否有解决方法如何从工作人员外部调用对象?

2 个答案:

答案 0 :(得分:3)

JavaScript模型当然不是基于线程的,而是基于事件的。在多线程环境中无法锁定数据并确保其完整性。

这就是为什么多线程方案(其中包括webworkers)不允许数据共享(“全局”功能是一些数据并且通常通过闭包指向数据)。您无法从您的网络工作者调用“全局”功能。 You communicate with messages

您可以设置一个事件监听器来代替全局函数:

var myWorker = new Worker("my_task.js");
myWorker.onmessage = function (oEvent) {
   // the implementation of your "global function", for example :
   sendAndWaitCommand(oEvent.data.commandToSend);
};

答案 1 :(得分:0)

如果要使用util.js中的代码,则必须使用importScripts命令导入它:

MDF的例子:

importScripts();                        /* imports nothing */
importScripts('foo.js');                /* imports just "foo.js" */
importScripts('foo.js', 'bar.js');      /* imports two scripts */

请注意,如果util.js与全局范围交互,则这将无效,因为在导入之后,它仍将与您的工作者位于同一范围内。如果util.js包含执行sendAndWaitCommand所需的所有代码,那么这可能是一个不错的选择。

如果sendAndWaitCommand与您的其他代码(jquery.ajax,您的错误处理代码等)交互,那么设置消息和事件系统可能会更好,如下所示:

var worker = new Worker('uploadToDevice.js');
worker.onMessage = function (message) {
    if (// Test here to see if message is result
        message && message[0] == "!")
        myApp.onDone(message.substr(1)) // Removes the ! and calls a function to handel the worker being done
    else // assume the message is a sendAndWaitCommand request
        sendAndWaitCommand(message).then(function (a) {
            worker.postMessage(a); // Send the worker the result
        });  
worker.postMessage(SplitedFile); // Start the worker

第二种方法可能涉及对代码进行更多重构,但可能需要正确使用工作程序。