瀏覽器執行javascript的代碼是單線程的,所以瀏覽器的UI線程不能同時處理UI界面的變化和javascript的代碼執行。由於UI線程一次只能處理一個任務,因此有一個任務隊列來存放即將要執行的任務。線程中當前任務執行完畢後,接着執行隊列中的第一個任務。javascript
當一段javascript代碼的執行時間大於100毫秒,就會對用戶體驗產生影響。所以最好將任務的執行時間控制在50毫秒之內。當須要循環大量數組或者執行一系列耗時任務時,能夠使用定時器將任務分解。java
假如要執行連續的三個耗時任務:web
//封裝多任務執行函數
function multipleTask(items,callback){
var tasks = items.concat(),func;
setTimeout(func = function(){
if(tasks.length>0){
var task = tasks.shift();
task();
setTimeout(func,25);
}else{
callback();
}
},25);
}
function step_1(){
console.log('step_1 is runing.');
}
function step_2(){
console.log('step_2 is runing.');
}
function step_3(){
console.log('step_3 is runing.');
}
//調用執行
function run(){
var items = [step_1,step_2,step_3];
multipleTask(items,function(){
console.log('multipleTask is over.');
});
}
複製代碼
假設要進行的一系列任務並不全是耗時長的,要避免兩個耗時任務連續執行,又要避免短時耗的任務佔用一次定時任務,須要作一些優化:數組
function timedMultipleTask(items,callback){
var tasks = items.concat(),func;
setTimeout(func = function(){
var start = +new Date(),task;
do{
task = tasks.shift();
task();
}while(tasks.length>0&&new Date()-start>50)
if(tasks.length>0){
setTimeout(func,25);
}else{
callback();
}
},25);
}
複製代碼
webworker是獨立於UI線程的,每個webworker都擁有本身的線程,不會影響到UI界面的變化。webworker擁有本身的運行環境,同時也可以和網頁代碼經過事件接口進行通訊。webworker適合處理須要大量計算的場景,圖像的計算,大數組的排序,解碼/編碼大字符串等。瀏覽器
假設須要從新排序一個大數組:bash
//web代碼
var arr = [...];
var worker = new Worker('webworker.js');
worker.postMessage(arr);
worker.onmessage = function(event){
var arr = event.data;
process(data); //處理排完序的數組
}
//webworker代碼
function arrSort(arr){
var sortedArr = process(); //從新排序arr
return sortedArr;
}
self.onmessage = function(event){
var arr = event.data,
sortedArr = arrSort(arr);
self.postMessage(sortedArr);
}
複製代碼