- js引擎线程 (解释执行js代码、用户输入、网络请求)
- GUI线程 (绘制用户界面、与js主线程是互斥的)
- http网络请求线程 (处理用户的get、post等请求,等返回结果后将回调函数推入任务队列)
- 定时触发器线程 (setTimeout、setInterval等待时间结束后把执行函数推入任务队列中)
- 浏览器事件处理线程 (将click、mouse等交互事件发生后将这些事件放入事件队列中)
解析
①JS可以操作DOM元素,进而会影响到GUI的渲染结果,因此JS引擎线程与GUI渲染线程是互斥的。也就是说当JS引擎线程处于运行状态时,GUI渲染线程将处于冻结状态。
②JavaScript是基于单线程运行的,同时又是可以异步执行的。
③setTimeout的等待时间结束后并不是直接执行的而是先推入浏览器的一个任务队列,在同步队列结束后在依次调用任务队列中的任务。
setTimeout(function(){}, 0)Js主线程中的执行栈为空时,0毫秒实际上也达不到的,根据HTML标准,最低4毫秒。
setInterval是每隔一段时间把任务放到Event Queue之中
代码
同步与异步
// 同步【执行栈】
function foo(ot){
function bar(it){
debugger;
console.log(it);
}
bar(20);
console.log(ot);
}
foo();
0.代码没有执行的时候,执行栈为空栈
1.foo函数执行时,创建了一帧,这帧中包含了形参、局部变量(预编译过程),然后把这一帧压入栈中
2.然后执行foo函数内代码,执行bar函数
3.创建新帧,同样有形参、局部变量,压入栈中
4.bar函数执行完毕,弹出栈
5.foo函数执行完毕,弹出栈
6.执行栈为空
执行栈其实相当于js主线程
$.ajax({
url: ‘localhost:/js/demo.json’,
data: {},
success: function (data) {
console.log(data);
}
});
console.log(‘run’);
Ajax 进入Event Table,注册回调函数success
执行console.log(‘run’)
ajax事件完成http网络请求线程把任务放入Event Queue中
主线程(调用栈)读取任务下执行success函数
定时器
// 获得当前时间
var startTime = +new Date()
function sleep(time) {
for (var i = 0; i < time; i++) {
console.log(i);
}
}
console.log(startTime);
setTimeout(function () {
console.log(+new Date() - startTime);
// 延迟100毫秒
}, 100)
sleep(10000);