最近項目中要用一個倒計時,但是當彈窗的時候倒計時會被阻塞,所以我想到使用Javascript多線程解決該問題。
雖然JavaScript是單線程的,但是通過worker可以讓Javascript另外開一個線程來執行你想執行的js文件
let worker = new Worker('js文件路徑');
線程之間的通信方式
主線程
worker.PostMessage(你想傳輸的數據);
worker.onmessage = function(event){
//event.data是子線程返回的數據
}
子線程
onmessage 接收主線程數據
PostMessage 向主線程發送數據
舉一個栗子:
<!DOCTYPE html> <html lang="zh"> <head> <title>多線程</title> <meta charset="utf-8"/> <meta name="Description" content=""/> <meta name="Author" content="巽秋"/> <style type="text/css"></style> </head> <body> <div> <span id="hour"></span>:<span id="minute"></span>:<span id="second"></span> </div> <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script> <script> let worker = new Worker('./index.js'); worker.postMessage(new Date().getTime()+1000000); worker.onmessage = function (event) { $("#hour").text(event.data.hour); $("#minute").text(event.data.minute); $("#second").text(event.data.second); } </script> </body> </html>
上面我在script中讓當前文件夾下的index用新的進程執行
下面是index中的代碼
onmessage = function (event) { let end_time = event.data; if(end_time>new Date().getTime()){ end_time=end_time/1000; setInterval(function(){ let now_time = Math.round(new Date().getTime()/1000); //現在的時間 let time =end_time - now_time; let hour = parseInt(time / 60 / 60 ); let minute = parseInt(time / 60 % 60); let seconds = parseInt(time % 60); if(now_time<= end_time){ if(hour < 10){ hour = "0" + hour; } if(minute < 10){ minute = "0" + minute; } if(seconds < 10){ seconds = "0" + seconds; } postMessage({hour:hour,minute:minute,second:seconds}); //返回這一秒的數據 } },1000); } };
這樣一來雖然彈窗的時候數字不再倒計時了,但是實際上在另一個線程中的js在倒計時,所以這樣一來問題就解決了