Javascript執行機制
在HTML5之前,瀏覽器中JavaScript的運作都是以單執行緒的方式運作的,雖然有多種方式實現了對多執行緒的模擬(例如:Javascript 中的setinterval 方法,setTimeout 方法等),但是本質上程式的運作仍然是由JavaScript 引擎以單一執行緒調度的方式進行的。的多執行緒- WebWorker
HTML5 中的Web Worker 可以分為兩種不同執行緒類型,一個是專用執行緒Dedicated Worker,一個是共享執行緒Shared Worker。類型的執行緒各有不同的用途。可以與其他的worker或是瀏覽器元件通信,但是他不能與DOM通信。中都實現了,可以放心使用。 #就可以了。是誰向誰發送數據,發送發送使用的都是postMessage方法,接收方都是使用onmessage方法接收數據。 .data取得收到的資料。傳送吧。例如:postMessage({'cmd': 'init', 'timestamp': Date.now()});
當執行緒發生錯誤的時候,它的onerror事件回呼會被呼叫。所以處理錯誤的方式很簡單,就是掛接執行緒實例的onerror事件。這個回呼函數有一個參數error,這個參數有3個欄位:message - 錯誤訊息;filename - 發生錯誤的腳本檔案;lineno - 發生錯誤的行。
銷毀執行緒 在執行緒內部,使用close方法執行緒自己銷毀自己。在執行緒外部的主執行緒中,使用執行緒實例的terminate方法銷毀執行緒。
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.c
all
ee(n - 1) + arguments.callee(n - 2);
};
onmessage = function(event) {
var n = parseInt(event.data, 10);
postMessage(fibonacci(n));
};
把它們放到相同的目錄,執行頁面文件,檢視控制台,可以看到運行的結果。
worker.addEvent List ener('message', function(event) { console.log("Result:" + event.data); }, false);個人覺得很麻煩,不如用onmessage直接。
類別庫。例如以下都是合法的使用方式:importScripts();
importScripts('foo.js');
importScripts('foo.js', 'bar.js');
匯入以後,可以直接使用這些檔案中的方法。看一個網路上的小範例:mportScripts('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方法解決資源預載的問題(瀏覽器預先載入資源,而不會對資源進行解析與執行),道理也很簡單。
執行緒巢狀
在工作執行緒中還可以在建立子執行緒,各種操作還是一樣的。
同步問題
Worker沒有鎖定的機制,多執行緒的同步問題只能靠程式碼來解決(例如定義訊號變數
共享型SharedWebWorker
共享型web worker主要适用于多连接并发的问题。因为要处理多连接,所以它的API与专用型worker稍微有点区别。除了这一点,共享型web worker和专用型worker一样,不能访问DOM,并且对窗体属性的访问也受到限制。共享型web worker也不能跨越通信。
页面脚本可以与共享型web worker通信,然而,与专用型web worker(使用了一个隐式的端口通信)稍微有点不同的是,通信是显式的通过使用一个端口(port)对象并附加上一个消息事件处理程序来进行的。
在收到web worker脚本的首个消息之后,共享型web worker把一个事件处理程序附加到激活的端口上。一般情况下,处理程序会运行自己的postMessage()方法来把一个消息返回给调用代码,接着端口的start()方法生成一个有效的消息进程。
看网上能找到的的唯一个例子:创建一个共享线程用于接收从不同连接发送过来的指令,然后实现自己的指令处理逻辑,指令处理完成后将结果返回到各个不同的连接用户。
HTML代码:
<script> 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() 方法来启动这个端口。之后就可以像工作线程的使用方式一样正常的接收和发送消息。
线程中能做的事:
1.能使用setTimeout(), clearTimeout(), setInterval(),clearInterval()等函数。
2.能使用navigator对象。
3.能使用XMLHttpRequest来发送请求。
4.可以在线程中使用Web Storage。
5.线程中可以用self获取本线程的作用域。
线程中不能做的事:
1.线程中是不能使用除navigator外的DOM/BOM对象,例如window,document(想要操作的话只能发送消息给worker创建者,通过回调函数操作)。
2.线程中不能使用主线程中的变量和函数。
3.线程中不能使用有"挂起"效果的操作命令,例如alert等。
4.线程中不能跨域加载JS。
线程也是需要消耗资源的,而且使用线程也会带来一定的复杂性,所以如果没有充足的理由来使用额外的线程的话,那么就不要用它。
以上是HTML5之Javascript多執行緒的詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!