Home > Article > Web Front-end > Let’s talk about JavaScript threads_javascript skills
Code Judgment 1:
<div id="div"> click me </div> <script> var div=document.getElementById("div"); div.addEventListener('click',function(){ alert('You have clicked me!'); }); for(var i =0; i<999999999;i++){ console.log(i); } </script>
When executed, all browsers will freeze if nothing else happens, because there are too many for loops above, which consumes a lot of CPU resources. Based on the fact that JavaScript is single-threaded, the browser UI rendering is suspended and causes suspended animation. .
Now the question comes, I just want to implement the above code, what should I do?
Concurrent.Thread.js
This class library essentially uses setTimeout to implement a "fake multi-threading". Was a good choice before HTML5 WebWorker came out. For example, if we want to implement the above "code snippet 1", we can write it like this (click me to download the class library):
Code snippet 2:
<div id="div"> click me </div> <script src="Concurrent.Thread.js"></script> <script> Concurrent.Thread.create(function(){ var div=document.getElementById("div"); div.addEventListener('click',function(){ alert('You have clicked me!'); }); for(var i =0; i<9999999;i++){ console.log(i); } }); </script>
A "new thread" can be created through the create method provided by this class library. In addition, setting the type attribute of the script tag to text/x-script.multithreaded-js can also achieve the same effect:
Code fragment three:
<div id="div"> click me </div> <script src="Concurrent.Thread.js"></script> <script type="text/x-script.multithreaded-js"> var div=document.getElementById("div"); div.addEventListener('click',function(){ alert('You have clicked me!'); }); for(var i =0; i<9999999;i++){ console.log(i); } </script>
WebWorker
How can HTML5 turn a blind eye to the poor user experience of the above browsers being stuck?
Next we use the classic Fibonacci sequence to test:
Code fragment four:
Main page:
<div id="div"></div> <script> window.onload=function(){ var div=document.getElementById("div"); if(typeof(Worker)!=="undefined"){//在创建WebWorker之前,先判断浏览器是否支持 console.log("Start calculating...."); var time1= new Date()*1;//获得当前时间戳 var worker=new Worker("fibonacci.js");//创建WebWorker对象,并传递在新线程中将要执行的脚本的路径 worker.onmessage=function(e){ //监听从新线程发送过来的数据 div.innerHTML=e.data; var time2=new Date()*1; console.log("time spend:"+(time2-time1)+"ms"); } worker.postMessage(36);//向新线程发送数据 }else{ alert("Your browser do not support WebWoker"); } } </script> fibonacci.js: var fibonacci=function (n){ return n<3?n:(arguments.callee(n-1)+arguments.callee(n-2)); } onmessage=function(e){ var num=parseInt(e.data,10); postMessage(fibonacci(num));//向主页面发送数据 }
The basic usage has been commented in the code. Looking at the console, you can see that the execution time will be printed out soon. So we came to the conclusion that WebWorker is suitable for performing complex and large-scale calculations on the front end. It should be noted that WebWorker does not support cross-domain. Local testing should still use the http protocol. Do not use the file protocol. Otherwise, the Worker object cannot be created and a script error will be reported.
If we need to perform multiple postMessage operations continuously, it is best not to write work.postMessage all the time, like this:
worker.postMessage(36); worker.postMessage(36); worker.postMessage(36);
Because there is only one WebWorker instance at this time, postMessage will be executed sequentially instead of asynchronously, so its performance cannot be fully utilized. Data can be sent by creating multiple WebWorker instances.
A few things to note are:
1. We observed that WebWorker creates a worker by accepting a url, and the implementation principle of jsonp is to load data by dynamically inserting script tags. Wouldn't it be better if we try to use WebWorker to achieve the same thing? Because WebWorker is multi-threaded and has no blocking, wouldn't it be beautiful? But in fact, after experiments, we found that the performance of WebWorker was not satisfactory. So this is not what it is good at, we should not let it take over.
2. When WebWorker accepts information from other sources, it actually brings hidden dangers to the security of the site. If it receives script information from unknown sources, it may lead to XSS injection attacks. So this needs to be guarded against. In fact, it is unsafe to use innerHTML in our example above. You can use innerText or textContent provided by modern browsers instead to filter out html tags.
I’m quite tired today and want to sleep, so I’ll write this much for now.