当前位置: 首页 > Web前端 > HTML5

前端实训-中级阶段(24)-WebWorkers多线程(2019-11-07期)

时间:2023-04-05 19:18:03 HTML5

前端最基础的就是HTML+CSS+Javascript。掌握这三项技术算是入门,但也只是入门而已。现在前端开发的定义远不止于此。前端小课堂(HTML/CSS/JS),本着提高技术水平,夯实基础知识的中心思想,开课(每周四)。JS是单线程、事件循环模型。在使用上,如果有大量高强度的计算,UI渲染过程就会卡住。根据FPS:60来计算1000ms/60=16.666ms。我们程序的占用时间需要小于16.666ms。WebWorkers用法newWorker(url)将在工作线程中运行代码,这与主线程不同。因为不是浏览器环境,所以不能使用DOM和window。当然也有一些API可以使用localstroage、websocket、indexDB、XMLHttpRequest等,没问题。同时分为两个环境。独占模式:DedicatedWorkerGlobalScope(一个专用线程对应一个主线程)共享模式:SharedWorkerGlobalScope(一个共享线程对应多个主线程)postMessage()方法用于在主线程和工作线程之间发送信息,onmessage事件被BB监听。数据通过传递副本而不是直接共享数据来传输。因此,有时传输损耗高于计算损耗。当然,它也支持将整体内存交给worker,但是如果这样使用,主线程将无法访问到这些内容。测试地址工作者独占线程(DedicatedWebWorker)在创建时只能供主线程使用。//htmlwk=newWorker('/static/workers/1190000020913212.js');demo2.addEventListener('click',function(){wk.postMessage(str)})//1190000020913212.jsonmessage=function(e){varstr=e.data;console.time('reportString');console.log(str.length,str.split('').join('+').length)console.timeEnd('reportString');}SharedWorker可以在同一个域被多个窗口和多个脚本运行时进行通信。比如iframe,标签页。//htmlswkPIP=newSharedWorker('/static/workers/1190000020913212-SharedWorker-pip.js');swkPIP.port.start();swkPIP.port.postMessage(args)//worker.jsvarportArr=[];onconnect=function(e){varport=e.ports[0];portArr.push(port)port.addEventListener('message',function(e){console.log(self,e,port)if(e.data.type=='private'){port.postMessage(['pip',e.data]);}elseif(e.data.type=='public'){portArr.forEach(v=>v.postMessage(['pip',e.data]))}elseif(e.data.type=='publicNoSelf'){portArr.forEach(v=>v!=port&&v.postMessage(['pip',e.data]))}});端口.start();//使用addEventListener时需要。否则由onmessagesetter隐式调用。}从实现代码可以看出。SharedWorkers需要使用prot通道。还需要start()打开通道。可实现的效果跨窗口通信比如有一些轮询接口,在多窗口场景下会形成密集访问。如果我们将请求转移到SharedWorker,SharedWorker就会节流。拉回数据并通知每个窗口。例如,当用户在一个窗口登录时,将登录状态通知给其他窗口。ServiceWorkers用于浏览器和服务器之间的代理服务。可以实现离线访问,拦截请求,更新缓存等。navigator.serviceWorker.register('/static/js/sw-20190621.js')其他事项通过URL.createObjectURL()创建一个URL对象,可以创建一个嵌入式工人。打开一个worker需要一个同源URL。有时我们不需要这样的文件,那么我们可以传递一个指向内存的URL。//worker.jsvarstr=`vari=0;函数测试(){postMessage(++i);设置超时(测试,1000);}test();`;//htmlvarblob=newBlob([str]);varwk=newWorker(window.URL.createObjectURL(blob));通过传递对象来传递数据默认情况下,主线程和worker之间的数据传递是通过复制,即在JSON.stringify()之后发送,接受使用JSON.parse()进行处理。这样一来,就会在序列化和反序列化中丢失一部分。所以worker为我们提供了一种更高效的方式来传入整块数据(整块内存都交出来了,源环境将无法访问)。myWorker.postMessage(uInt8Array,[uInt8Array]);通过postMessage的第二个入参,我们将整个uInt8Array对象发送出去。我们都知道执行环境的上下文。浏览器环境的上下文和Node环境的上下文不同,有些是浏览器环境特有的。工作环境也不一样。其中self指向当前环境的global,与Window不是同一个对象,而是WorkerGlobalScope。微信公众号:前端linong参考前端训练目录,前端训练规划,前端训练计划https://www.sitepen.com/blog/the-return-of-sharedarraybuffers-and-atomics/JavaScript性能工具——Webworker