浏览器执行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);
}
复制代码