Javascript执行机制 Javascript中的多线程 - WebWorker 专用型web worker 专用型worker与创建它的脚本连接在一起,它可以与其他的worker或是浏览器组件通信,但是他不能与DOM通信。专用的含义,就是这个线程一次只处理一个需求。专用线程在除了IE外的各种主流浏览器中都实现了,可以放心使用。 线程通信 发送JSON数据 处理错误 销毁线程 HTML代码: <script type="text/javascript">onload = function(){ var worker = new Worker('fibonacci.js'); worker.onmessage = function(event) { console.log("Result:" event.data); }; worker.onerror = function(error) { console.log("Error:" error.message); }; worker.postMessage(40); } </script> 脚本文件fibonacci.js代码: //fibonacci.js var fibonacci = function(n) { return n < 2 ? n : arguments.callee(n - 1) arguments.callee(n - 2); }; onmessage = function(event) { var n = parseInt(event.data, 10); postMessage(fibonacci(n)); }; 把它们放到相同的目录,运行页面文件,查看控制台,可以看到运行的结果。 console.log("Result:" event.data); }, false); 个人觉得很麻烦,不如用onmessage直接。
importScripts('foo.js'); importScripts('foo.js', 'bar.js'); 导入以后,可以直接使用这些文件中的方法。看一个网上的小例子: importScripts('math_utilities.js'); onmessage = function (event) { var first = event.data.first; var second = event.data.second; calculate(first,second); }; function calculate(first,second) { //do the calculation work var common_divisor=divisor(first,second); var common_multiple=multiple(first,second); postMessage("Work done! " "The least common multiple is " common_divisor " and the greatest common divisor is " common_multiple); } 网上也有网友想到了利用这里的importScripts方法解决资源预加载的问题(浏览器预先加载资源,而不会对资源进行解析和执行),道理也很简单。
线程嵌套
共享型SharedWebWorker 在收到web worker脚本的首个消息之后,共享型web worker把一个事件处理程序附加到激活的端口上。一般情况下,处理程序会运行自己的postMessage()方法来把一个消息返回给调用代码,接着端口的start()方法生成一个有效的消息进程。 var worker = new SharedWorker('sharedworker.js'); var log = document.getElementByIdx_x_x_x_x('response_from_worker'); worker.port.addEventListener('message', function(e) { //log the response data in web page log.textContent =e.data; }, false); worker.port.start(); worker.port.postMessage('ping from user web page..'); //following method will send user input to sharedworker function postMessageToSharedWorker(input) { //define a json object to construct the request var instructions={instruction:input.value}; worker.port.postMessage(instructions); } </script> 脚本文件代码: // 创建一个共享线程用于接收从不同连接发送过来的指令,指令处理完成后将结果返回到各个不同的连接用户。var connect_number = 0; onconnect = function(e) { connect_number =connect_number 1; //get the first port here var port = e.ports[0]; port.postMessage('A new connection! The current connection number is ' connect_number); port.onmessage = function(e) { //get instructions from requester var instruction=e.data.instruction; var results=execute_instruction(instruction); port.postMessage('Request: ' instruction ' Response ' results ' from shared worker...'); }; }; function execute_instruction(instruction) { var result_value; //implement your logic here //execute the instruction... return result_value; } 在上面的共享线程例子中,在主页面即各个用户连接页面构造出一个共享线程对象,然后定义了一个方法 postMessageToSharedWorker 向共享线程发送来之用户的指令。同时,在共享线程的实现代码片段中定义 connect_number 用来记录连接到这个共享线程的总数。之后,用 onconnect 事件处理器接受来自不同用户的连接,解析它们传递过来的指令。最后,定义一个了方法 execute_instruction 用于执行用户的指令,指令执行完成后将结果返回给各个用户。 这里我们并没有跟前面的例子一样使用到了工作线程的 onmessage 事件处理器,而是使用了另外一种方式 addEventListener。实际上,前面已经说过,这两种的实现原理基本一致,只是在这里有些稍微的差别,如果使用到了 addEventListener 来接受来自共享线程的消息,那么就要先使用 worker.port.start() 方法来启动这个端口。之后就可以像工作线程的使用方式一样正常的接收和发送消息。
线程中能做的事: 5.线程中可以用self获取本线程的作用域。
线程中不能做的事:
线程也是需要消耗资源的,而且使用线程也会带来一定的复杂性,所以如果没有充足的理由来使用额外的线程的话,那么就不要用它。 来源:http://www./content-1-52001.html |
|