webWorker 异步加载

一个异步的脚本,不会阻塞浏览器渲染,运行在另一个全局上下文中,不能使用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)
})


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值