ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
* [TOC] > [阮一峰参考网站](http://javascript.ruanyifeng.com/htmlapi/webworker.html#toc2) ## 概述 Web Worker为Web内容在后台线程中运行脚本提供了一种简单的方法。线程可以执行任务而不干扰用户界面 **注意事项:** 1. 同源限制 分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。 2. DOM 限制 Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象。但是,Worker 线程可以navigator对象和location对象。 3. 通信联系 Worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成。 4. 脚本限制 Worker 线程不能执行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。 5. 文件限制 Worker 线程无法读取本地文件,即不能打开本机的文件系统 `file://`,它所加载的脚本,必须来自网络。 6. 数据拷贝 在主页面与 worker 之间传递的数据是通过**拷贝** ### 语法 ``` // 监听事件 onmessage onmessageerror // 发送通讯数据 postMessage // 关闭 work terminate ``` ### 专用worker main.js ``` var myWorker = new Worker('worker.js'); const first = document.querySelector('#number1'); first.onchange = function() { myWorker.postMessage([first.value,second.value]); console.log('Message posted to worker'); } ``` work.js ``` onmessage = function(e) { console.log('Message received from main script'); var workerResult = 'Result: ' + (e.data[0] * e.data[1]); console.log('Posting message back to main script'); postMessage(workerResult); } ``` ### 生成subworker Worker 线程中可使用全局函数`importScripts()`来引入脚本,该函数接受0个或者多个URI作为参数来引入资源 ``` importScripts(); /* 什么都不引入 */ importScripts('foo.js'); /* 只引入 "foo.js" */ importScripts('foo.js', 'bar.js'); /* 引入两个脚本 */ ``` ### 共享worker 一个共享worker可以被多个脚本使用——即使这些脚本正在被不同的window、iframe或者worker访问 ``` var myWorker = new SharedWorker('worker.js'); myWorker.port.start(); // 父级线程中的调用 squareNumber.onchange = function() { myWorker.port.postMessage([squareNumber.value,squareNumber.value]); console.log('Message posted to worker'); } ``` work.js ``` onconnect = function(e) { var port = e.ports[0]; port.onmessage = function(e) { var workerResult = 'Result: ' + (e.data[0] * e.data[1]); port.postMessage(workerResult); } } ``` ## 示例 ## 嵌入式 work ``` <script type="text/js-worker"> console.log("hello") </script> <script type="text/js-worker"> console.log("hello-1") </script> <script> document.querySelectorAll("script[type=\"text\/js-worker\"]").forEach(item=>{ new Worker("data:text/javascript;charset=US-ASCII,"+encodeURIComponent(item.innerHTML)) }) </script> ```