一般,浏览器执行某段程序的时候会阻塞直到运行结束后在恢复到正常状态,而HTML5的Web Worker就是为了解决这个问题。经过worker线程完成密集计算,避免程序的阻塞和页面的卡顿(fps太低)html
用fibonacci数列来模拟测试web
worker-test.htmlajax
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>测试 web worker</title> </head> <body> <script> function fibonacci(n) { return n < 2 ? n : arguments.callee(n - 1) + arguments.callee(n - 2); } function testNoWorker() { let start = Date.now(); fibonacci(38); let end = Date.now(); console.log(end - start); // wait a long time.. } function testUseWorker() { let start = Date.now(); let worker = new Worker('worker.js'); worker.postMessage(38); worker.addEventListener('message', function (event) { let end = Date.now(); console.log('worker result: ', end -start); }); console.log('can do other jobs, when worker is computing'); } testNoWorker(); testUseWorker(); </script> </body> </html>
worker.jsjson
function fibonacci(n) { return n < 2 ? n : arguments.callee(n-1) + arguments.callee(n-2); } self.addEventListener('message', function (event) { let result = fibonacci(event.data); self.postMessage(result); }); // 可用 setTimeout , setInterval setTimeout(() => { console.log('timeout..'); }, 100); setInterval(() => { console.log('setInterval...'); }, 200); // 可发起ajax fetch('data.json').then(res => res.json()).then(data => {console.log(data, '<--json data')}); // 可访问 location, navigator console.log(location); console.log(navigator); // worker.js的执行上下文为 self (worker实例), // self上的属性和方法可直接调用 console.log(typeof addEventListener); console.log(typeof postMessage);
假设主页面须要屡次执行耗时的操做(如: fibonacci), 可以下用worker来异步执行.跨域
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>测试 实例化多个 web worker</title> </head> <body> <script> function fibonacci(n) { let start = Date.now(); let worker = new Worker('worker.js'); worker.addEventListener('message', function (event) { let end = Date.now(); console.log('worker result: ', end - start); }); worker.postMessage(n); } /* 同时跑多个worker, 会下降每一个worker线程的性能;但总比阻塞页面要好 */ fibonacci(38); console.log('after one'); fibonacci(38); console.log('after two'); fibonacci(38); console.log('after three'); console.log('can handle other jobs..'); </script> </body> </html>
在主页面实例化worker, new Worker('/url/to/worker.js')
worker脚本必须和主页面同域;在worker脚本中,能够 self.importScripts('url/to/script.js')
导入任何域的脚本, 多个 self.importScripts()
是顺序同步加载的浏览器
worker.terminate()
终止worker线程