浏览器的主要进程
- Browser进程
- 第三方插件进程
- GPU进程
- 渲染进程
渲染进程中的主要线程
-
GUI渲染进程
-
JS引擎线程(主要线程)
-
事件触发线程
事件触发线程管理着一个 事件队列[fn1,fn2,success],队列中包含已触发事件的回调函数,等待被JS引擎线程空闲时来调用
-
定时器线程
-
异步http请求线程
当我们发送ajax请求时,等待响应状态改变/响应结果都是异步http请求线程在处理; 当请求完成时,触发事件,事件触发线程将对应的回调函数加入事件队列
页面渲染流程
- 从上到下解析html标签,构建DOM树
- 解析CSS样式,构建CSSOM样式树
- 根据DOM树和CSSOM样式树,计算生成渲染树
- 根据渲染树渲染页面
事件循环机制(Event loop)
- js引擎解析代码,将同步任务按照执行顺序加入执行栈/调用栈(call stack),然后按照顺序依次执行
- js解析到异步任务时,不会立即执行、等待异步的结果,而是交给其他线程来处理,继续执行同步任务
- 其他线程处理完异步任务后,对应的回调函数加入事件队列,等待js引擎空闲时来执行
- 异步任务的回调函数在调用时,又有其他同步、异步任务,重复上述步骤
promise
setTimeout(()=>{// f1
console.log( 0 );
},0);
new Promise((resolve,reject)=>{// f2
console.log( 1 );
resolve();
}).then(()=>{// f3
console.log( 2 );
new Promise((resolve,reject)=>{// f4
console.log( 3 );
resolve();
}).then(()=>{// f5
console.log( 4 );
}).then(()=>{// f6
console.log( 5 );
})
}).then(()=>{// f7
console.log( 6 );
});
new Promise((resolve,rejpect)=>{// f8
console.log( 7 );
resolve();
}).then(()=>{// f9
console.log( 8 );
});
(异步)微队列:[f3,f9,f5,f7,f6]
宏队列:setTimeout f1
new Promise()//f2
console.log( 1 );
resolve(); 状态 -> fulfilled -> 将f3加入微队列
new Promise()//f8
console.log( 7 );
resolve(); 状态 -> fulfilled -> 将f9加入微队列
此时js空闲,优先处理微队列,取出f3
console.log( 2 );
new Promise()
console.log( 3 );
resolve(); 状态 -> fulfilled -> 将f5加入微队列
此时f3执行完成(fulfilled),将f7加入微队列
此时js空闲,优先处理微队列,取出f9
console.log( 8 );
此时js空闲,优先处理微队列,取出f5
console.log( 4 );
由于return undefined -> fulfilled -> 将f6加入微队列
此时js空闲,优先处理微队列,取出f7
console.log( 6 );
此时js空闲,优先处理微队列,取出f6
console.log( 5 );
此时js空闲,处理宏队列
console.log( 0 )
结果:1,7,2,3,8,4,6,5,0
异步函数
async function async1(){
console.log( 1 );
let res = await async2();
console.log( 2 );
}
async function async2(){
console.log( 3 );
}
console.log( 4 );
setTimeout(()=>{// f1
console.log( 5 );
});
async1();
new Promise((resolve,reject)=>{// f2
console.log( 6 );
resolve();
}).then(()=>{// f3
console.log( 7 );
});
console.log( 8 );
微队列:[await,f3]
宏队列:setTimeout f1
console.log( 4 );
async1();
console.log( 1 );
//let res = await async2();
async2();
console.log( 3 );
await 会跳出当前的执行流,继续执行后面的同步程序
await 返回的是一个promise对象,加入微队列
new Promise()
console.log( 6 );
resolve(); 状态 -> fulfilled -> 将f3加入微队列
console.log( 8 );
此时js空闲,优先处理微队列,继续执行await后的程序
console.log( 2 );
此时js空闲,优先处理微队列,取出f3
console.log( 7 );
此时js空闲,处理宏队列
console.log( 5 );
结果:4,1,3,6,8,2,7,5