对于小球运动的场景题,后来在掘金看到了系统的答法(链表树、web worker ...)。别人说webworker是应该了解的,但是我之前没接触过,了解一下吧。
什么是web worker
当在 HTML 页面中执行脚本时,页面的状态是不可响应的,直到脚本已完成。
web worker 是运行在后台的 js线程,不似js主线程与渲染引擎公用。Worker 线程一旦新建成功,就会始终运行,这样有利于随时响应主线程的通信。但是,这也造成了 Worker 比较耗费资源,不应该过度使用,而且一旦使用完毕,就应该关闭。
兼容性上IE之外的浏览器都支持!
检测 Web Worker 支持
官网给出的方法。
if(typeof Worker !=="undefined") {
// Yes! Web worker support!
// Some code.....
} else {
// Sorry! No Web Worker support..
}
实际上,要用一个变量存放 Worker 线程对象还需要判断它是不是正存放一个Worker线程对象。
if(typeof Worker !=="undefined") {
// Yes! Web worker support!
if(!myworker instanceof Worker ){
// You can new a Web Worker!
}
} else {
// Sorry! No Web Worker support..
}
创建 web worker 文件
创建一个js文件,用于载入worker线程
var data=10;
self.onmessage = function(e){
console.log(e);
for(i=0;i<data;i++){
console.log('worker: '+i);
//计算的代码
}
postMessage(data);
}
开启worker线程
在主线程开启woker线程
var worker = new Worker('子线程文件名.js'),
worker.postMessage(i);
worker.onmessage = function(e){
console.log(e.data);
}
两次看见了postMessage和onmessage ,postMessage用于向一端发送数据,onmessage用于在另一端监听数据。不巧的是,一番尝试,主线程先发,子线程只能在监听里回复,像一个请求响应一样。可能这就是主线程是主线程吧。
终止worker线程
worker.terminate();
注意事项
(1)同源限制
分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。
(2)DOM 限制
Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM
对象,也无法使用document
、window
、parent
这些对象。但是,Worker 线程可以navigator
对象和location
对象,还有自己作用域的self
对象。
(3)通信联系
Worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成。
(4)脚本限制
Worker 线程不能执行alert()
方法和confirm()
方法,但可以使用 XMLHttpRequest
对象发出 AJAX 请求。
(5)文件限制
Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。