webworker标准包含两部分:worker对象和WorkerGlobalScope(用来表示新创建的Worker的全局对象,也是worker线程内部使用的对象)
worker对象
var loader=new Worker("utils/loader.js");
创建一个新的worker,只需要使用Worker()构造函数,并将指定在Worker中运行的JavaScript脚本的URL传递给该构造函数即可。
如果URL采用的是相对路径,则是包含调用Worker()构造函数脚本的文档的URL为参造的。
而如果指定的URL采用的是绝对路径,那么必须和包含脚本的文档是同源的(同样的协议,主机名和接口)。
一旦获得Worker对象之后,就可以使用postMessage()方法来传递参数了。传递给postMessage()方法的值会复制,最终的副本会通过message事件传递给Worker。
loader.postMessage("file.txt");
要注意的是,Worker的postMessage()方法是没有参数的,但是window对象的postMessage()方法是有参数的。
可以通过监听Worker对象上的message事件来接受来自Worker的消息:
worker.onmessage=function(e){ var message=e.data; //从事件对象中获取消息 console.log("URL contents:"+message); }
如果Worker抛出了异常,并且它自己没有对其进行捕获和处理,可以作为监听的一个error事件来传递该异常。
worker.onerror=function(e){ //记录错误消息日志:包括Worker的文件名和行数 console.log("Error at"+e.filename+":"+e.lineno+":"+e.message); }
和所有的目标事件一样,worker对象也定义了标准的addEventListener()方法和removeEventListener()方法,如果想要管理多个事件处理程序,可以使用这些方法来代替onmessage和onerror属性。
Worker对象还有一个方法:terminate(),该方法强制一个Worker线程结束运行。
Worker作用域
通过Worker()构造函数创建一个新的Worker的时候,指定了包含JavaScript代码文件的URL,该代码会运行在一个全新的JavaScript运行环境中,完全和创建Worker的脚本隔离开来。WorkerGloableScope表示了该新的运行环境。
和Worker对象一样,WorkerGloableScope对象也有一个postMessage()方法和一个onmessage事件处理程序属性,不过使用方法恰好相反:在Worker中调用postMessage方法会触发Worker外部的一个message事件。worker外部传递的消息会转换成一个事件,传递给onmessage事件处理程序。
close()函数允许Worker将自己终止,但是在Worker对象上没有定义任何的API用于检测是否Worker已经将自己关闭了,也没有类似onerror事件处理函数,所以,在一个已经关闭的Worker上调用postMessage()方法,那么消息会无声无息地丢弃,而且也不会有任何的错误抛出。因此,如果一个Worker想要close()方法将自己关闭,那么最好先传递例如"关闭"这样的字样。
Check Web Worker Support
if(typeof(Worker) !== "undefined") {
// Yes! Web worker support!
// Some code.....
} else {
// Sorry! No Web Worker support..
}
Create a Web Worker File
Now, let's create our web worker in an external JavaScript.
Here, we create a script that counts. The script is stored in the "demo_workers.js" file:
var i = 0;
function timedCount() {
i = i + 1;
postMessage(i);
setTimeout("timedCount()",500);
}
timedCount();
View Code
The important part of the code above is the postMessage() method - which is used to post a message back to the HTML page.
Note: Normally web workers are not used for such simple scripts, but for more CPU intensive tasks.
Create a Web Worker Object
Now that we have the web worker file, we need to call it from an HTML page.
The following lines checks if the worker already exists, if not - it creates a new web worker object and runs the code in "demo_workers.js":
if(typeof(w) == "undefined") {
w = new Worker("demo_workers.js");
}
Then we can send and receive messages from the web worker.
Add an "onmessage" event listener to the web worker.
w.onmessage = function(event){
document.getElementById("result").innerHTML = event.data;
};
When the web worker posts a message, the code within the event listener is executed. The data from the web worker is stored in event.data.
Terminate a Web Worker
When a web worker object is created, it will continue to listen for messages (even after the external script is finished) until it is terminated.
To terminate a web worker, and free browser/computer resources, use the terminate() method:
w.terminate();
Reuse the Web Worker
If you set the worker variable to undefined, after it has been terminated, you can reuse the code:
w = undefined;
Full Web Worker Example Code
We have already seen the Worker code in the .js file. Below is the code for the HTML page:
Example
<!DOCTYPE html>
<html>
<body>
<p>Count numbers: <output id="result"></output></p>
<button onclick="startWorker()">Start Worker</button>
<button onclick="stopWorker()">Stop Worker</button>
<br><br>
<script>
var w;
function startWorker() {
if(typeof(Worker) !== "undefined") {
if(typeof(w) == "undefined") {
w = new Worker("demo_workers.js");
}
w.onmessage = function(event) {
document.getElementById("result").innerHTML = event.data;
};
} else {
document.getElementById("result").innerHTML = "Sorry! No Web Worker support.";
}
}
function stopWorker() {
w.terminate();
w = undefined;
}
</script>
</body>
</html>
View Code
Web Workers and the DOM
Since web workers are in external files, they do not have access to the following JavaScript objects:
- The window object
- The document object
- The parent object