一个异步的脚本,不会阻塞浏览器渲染,运行在另一个全局上下文中,不能使用window
特点:
.仅仅能被首次生成它的脚本使用,只能服务于新建它的页面,不同页面之间不能共享同一个 Web Worker。
.当页面关闭时,该页面新建的 Web Worker 也会随之关闭,不会常驻在浏览器中
.必须与主线程的脚本文件同源
.不能直接操作DOM节点
.不能使用window对象的默认方法和属性(如alert、confirm等)
.传输数据并不是被共享而是被复制。
.在同源的父页面中,workers可以依次生成新的workers
.线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络
.可以使用大量window对象之下的东西,包括WebSockets,IndexedDB以及FireFox OS专用的Data Store API等数据存储机制
基本使用:
if (window.Worker) {
const worker=new Worker(url,options)
}
url:表示worker将执行的脚本的URL、路径、类似blob这样的url,它必须遵守同源策略。
options:
type:该值可以是 classic 或 module. 如果未指定,将使用默认值 classic.
credentials:用以指定 worker 凭证,可以是 omit, same-origin,或 include。如果未指定,或者 type 是 classic,将使用默认值 omit (不要求凭证)
name:在 DedicatedWorkerGlobalScope 的情况下,用来表示 worker 的 scope 的一个 DOMString 值,主要用于调试目的
事件监听:
self:表示在worker内部使用的内置全局变量
(1)worker.onmessage、self.onmessage
var myWorker = new Worker('worker.js');
first.onchange = function() {
myWorker.postMessage([first.value,second.value]);
console.log('Message posted to worker');
}
myWorker.onmessage = function(e) {
result.textContent = e.data;
console.log('Message received from worker');
}
//worker.js
self.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');
self.postMessage(workerResult);
}
(2)错误监听
worker.onmessageerror、self.onmessageerror 数据序列化、反序列化错误时触发
worker.onerror、self.onerror 运行中错误
(3)监听在线、短线情况(可能存在兼容性问题)
self.onoffline=fn
self.ononline=fn
属性:
self.name 获取worker名称,即options中传入的name
self.location 获取类似浏览器url内容的location
self.navigator 获取navigator对象
方法:
(1)发送消息
worker.postMessage(data,[Transferable])、self.postMessage(data,[Transferable])
第二个参数为Transferable对象数组,意味着对象在内存中的位置也会被转移,即零拷贝转移
支持可转移的对象有:
ArrayBuffer、MessagePort、ReadableStream、WritableStream、TransformStream、AudioData、ImageBitmap、VideoFrame、OffscreenCanvas
多线程共享的内存:
SharedArrayBuffer
通过Atomics对象提供原子操作能力,解决多线程访问共享数据会出现数据竞争问题
(2)终止worker
worker.terminate();
self.close();
(3)向当前worker的作用域导入一或更多条脚本
self.importScripts('foo.js', 'bar.js',...);
也可用作JSONP
function MakeServerRequest()
{
importScripts("http://SomeServer.com?jsonp=HandleRequest");
}
JSONP回调
function HandleRequest(objJSON)
{
postMessage("Data returned from the server...FirstName: "
+ objJSON.FirstName + " LastName: " + objJSON.LastName);
}
代码示例:
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="iconfont/iconfont.css">
<link rel="stylesheet" href="css/1.css" type="text/css">
<script src='jq/jquery-3.4.1.js'></script>
<script src="js/bootstrap.min.js"></script>
<script src='js/swiper.jquery.min.js'></script>
<script src="js/swiper.animate1.0.2.min.js"></script>
<link rel="stylesheet" href="css/swiper.min.css">
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/animate.min.css">
<style>
</style>
</head>
<body>
<button>开启webWorker</button>
<script>
var num=1;
var timer=null;
timer=setInterval(function(){
console.log(num++);
},1000)
document.querySelector('button').onclick=function(){
var worker=new Worker('js/text1.js');
worker.onmessage=function(eve){
console.log(eve.data);
};
};
</script>
</body>
</html>
异步js文件:
setTimeout(function(){
console.log(22+'hh');
//写了postMessage回调函数才会执行
postMessage('黑皇');
},5000)
通过BlobURL实现:
var myTask = ` onmessage = function (e) { var data = e.data; data.push('hello'); console.log('worker:', data); // worker: [1, 2, 3, "hello"] postMessage(data); }; `;
var blob = new Blob([myTask]);
var myWorker = new Worker(window.URL.createObjectURL(blob));
myWorker.onmessage = function (e) {
var data = e.data;
console.log('page:', data); // page: [1, 2, 3, "hello"]
console.log('arr:', arr); // arr: [1, 2, 3]
};
var arr = [1,2,3];
myWorker.postMessage(arr);
通过DataURL实现:
// 由于Data URL的内容为必须压缩为一行,因此JavaScript无法利用换行符达到分号的效果。
const script = `addEventListener('message', event => { console.log(event.data); postMessage('echo'); }`
const worker = new Worker(`data:,${
script}`)
// 或 const worker = new Worker(`data:application/javascript,${script}`)
worker.onmessage = event => console.log(event.data)
worker.postMessage('main thread')
worker线程轮询
function createWorker(fn){
const blob = new Blob([fn.toString()])
const url = window.URL.createObjectURL(blob)
const worker = new Worker(url)
return worker
}
const webWorker = createWorker(function(){
let cache;
function compare(new, old){
... }
setInterval(()=>{
fetch('/api/xxx').then(res=>{
let data = res.data
if(!compare(data, cache)){
cache = data
self.postMessage(data)
}
})
},1000)
})
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/200794.html原文链接:https://javaforall.cn