有没有办法在一个文件中使用不同的工作程序功能

时间:2017-02-09 08:08:05

标签: javascript web-worker

阅读网络工作者我偶然发现了这个example来自mdn。 worker_add.js只是一次简单的功能。 因此,当我们向工作人员发布消息时,工作人员将启动myWorker.postMessage(["method", arg1, arg2]); 部分。在简单的例子中,工人只是乘以两个数字。但是,如果我想要一个也可以添加,划分等的工人怎么办?我是否需要为我希望我的工作人员运行的每个功能创建一个新的工作文件(例如if/else)?或者更清洁的方法是什么?

我在考虑将一个字符串作为工作人员的第一个参数发布

importScripts('emscripten.js')

onmessage = function(e) {
    console.log('Message received from main script.');
    if (e.data[0] == "method1")
    {
        Module.method1(e.data[1].byteOffset, e.data[2]);
        postMessage(e.data[1]);        
    }

    else if (e.data[0] == "method2")
    {
        var ret= Module.method2();
        postMessage(ret);
    }

    console.log('Posting message back to main script');
}

然后在我的工作者中我有CAST( CONCAT( CAST( CASE WHEN IFNULL(SM.start_date,'') = '' THEN'1911/01/01'ELSE SM.start_date END AS CHAR(10) ) ,'', CAST(CASE WHEN IFNULL(SM.start_time,'') = '' THEN'00:00:00'ELSE SM.start_time END AS CHAR(8) ) ) AS DATETIME) 个条件,检查字符串是否匹配,然后执行不同的代码。

scipy curvefit

3 个答案:

答案 0 :(得分:2)

我认为没有更好的方法来做你想要的事情,而是在信息本身内传递一些元数据。

但是,您的实施可以轻松改进。而不是切换器,只需将第一个参数视为函数名称,所有其他参数都是此函数的参数,函数结果将直接发回:

onmessage = function(e) {
  postMessage(Module[e.data[0]].apply(Module, e.data.slice(1)));
}

简单的一行关注你工作人员的任何数量的功能。

如果工作者函数结果是异步的,你可以检查函数结果是否为例如Promise并在留言resolve上发布消息,而不是直接发布消息。

答案 1 :(得分:2)

由于您可以传递字符串化的AJAX,因此您可以在工作人员中轻松实现条件逻辑。

只需传递一个参数告诉工人该做什么:

//This snippet won't run, it's just to illustrate

//main.js
var worker = new Worker('/js/worker.js');

worker.addEventListener("message", function(event) {
  if (event.data["do"] == "main") {
    console.log("One task complete");
  } else if (event.data["do"] == "second") {
    console.log("Other task complete");
  }
}, false);

function doMainTask(taskParam) {
  worker
    .postMessage({
      taskParam: JSON.stringify(taskParam),
      "do": "main"
    });
}

function doSecondTask(taskParam) {
  worker
    .postMessage({
      taskParam: JSON.stringify(taskParam),
      "do": "second"
    });
}

//worker.js

function messageHandler(event) {
  var obj = JSON.parse(event.data);

  var str = "";
  if (obj["do"] == "main") {
    str = main(obj.taskParam);
  } else if (obj["do"] == "second") {
    str = second(obj.taskParam);
  }
  this.postMessage({
    msg: str,
    "do": obj["do"],
    obj: obj
  });
}
this.addEventListener('message', messageHandler, false);

function main(taskParam) {
  return "main";
}
function second(taskParam) {
  return "second";
}

答案 2 :(得分:1)

根据埃米尔的回答,我在html5rocks找到了一个例子。我觉得这比Emil的答案稍微清晰一点。

主脚本看起来像这样

<button onclick="sayHI()">Say HI</button>
<button onclick="unknownCmd()">Send unknown command</button>
<button onclick="stop()">Stop worker</button>
<output id="result"></output>

<script>
  function sayHI() {
    worker.postMessage({'cmd': 'start', 'msg': 'Hi'});
  }

  function stop() {
    // worker.terminate() from this script would also stop the worker.
    worker.postMessage({'cmd': 'stop', 'msg': 'Bye'});
  }

  function unknownCmd() {
    worker.postMessage({'cmd': 'foobard', 'msg': '???'});
  }

  var worker = new Worker('doWork2.js');

  worker.addEventListener('message', function(e) {
    document.getElementById('result').textContent = e.data;
  }, false);
</script>

和工作人员doWork2.js是这样的:

self.addEventListener('message', function(e) {
  var data = e.data;
  switch (data.cmd) {
    case 'start':
      self.postMessage('WORKER STARTED: ' + data.msg);
      break;
    case 'stop':
      self.postMessage('WORKER STOPPED: ' + data.msg +
                       '. (buttons will no longer work)');
      self.close(); // Terminates the worker.
      break;
    default:
      self.postMessage('Unknown command: ' + data.msg);
  };
}, false);