讲多线程之前,我们先了解一下JS的事件机制
浏览器运行时,脚本必须定期让位给UI进程进行来维持网页的响应,闲置太长时间的脚本可能会被浏览器当成失控脚本,进而造成假死或弹窗
事件触发的设计javascript中的非阻塞IO机制让到来的消息在其他操作完成前排序等待,js以这种方式来模拟并发,它利用闭包、回调或promise来减少较慢操作的影响。
多线程:
举个例子:假如女朋友在洗澡,她洗澡需要30~60分钟,你不可能在卧室兴奋而焦急地等待这么长时间吧,总得找点事做吧,别TM兴奋过度,反而之后萎了,等她洗完,该干啥就干啥,其实多线线程,就是同一时刻,执行多个线程,并发处理任务
javascript本身的事件机制,决定了javascript是单线程来处理事务,但在实际应用中,往往需要使用多线程来计算一些复杂的逻辑,却不能影响页面的渲染及事件使用,这样,多线程处理,显得必不可少,那么现在介绍几种实现多线程的方式:
我们先看个例子
<script> document.getElementById('test').onclick = function(){ alert(1); } for(var i=0;i<100000;i++){ console.log(i); } </script>
浏览器直接卡死,或根本就没有反应,点击事件也用不了
What is the fuck? 这得多线程呀,咋弄?
1. Concurrent.Thread.js 适用于老式浏览器
小日本是牛逼呀,这个插件就像女优一样优秀,总能给人惊喜、试一试的冲动。
使用方式一:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <button id="test">测试</button> <script src="Concurrent.Thread-full-20080319.js"></script> <script> document.getElementById('test').onclick = function(){ alert('出来啦'); }; function cala(){ for(var i=0;i<100000;i++){ console.log(i); }; } Concurrent.Thread.create(cala); </script> </body> </html>
咋样,舒畅吧,头发去无踪,头屑更出众
使用方式二:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <button id="test">测试</button> <script src="Concurrent.Thread-full-20080319.js"></script> <script type="text/x-script.multithreaded-js"> document.getElementById('test').onclick = function(){ alert('射出来'); }; for(var i=0;i<100000;i++){ console.log(i); }; </script> </body> </html>
2. Worker 适用于支持H5的浏览器
不能在本地运行,需要在发布环境中执行
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <button id="test">测试</button> <script> document.getElementById('test').onclick = function(){ alert('射出来'); }; var worker; //检测浏览器是否支持Worker if(typeof(Worker) !== undefined){ worker = new Worker("worker.js"); worker.addEventListener("message",function(e){ //关闭worker worker.terminate(); },false); }else{ div.innerHTML = "IE已死,请更换浏览器!"; } </script> </body> </html>
worker.js 文件
for(var i=0;i<=100000;i++){ console.log(i); //通知主线程,已经计算完了 if(i==100000) postMessage(i); };