对于小球运动的场景题,后来在掘金看到了系统的答法(链表树、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://),它所加载的脚本,必须来自网络。