大前提
js 是单线程语言 ---------- 同一时间只做一件事
浏览器中常驻的进程
这些线程都由一个叫做UI主线程的来协调配置
GUI线程与js线程为互斥状态
js操作dom时 知道该进程完成时 gui 无法渲染页面 处于冻结状态
单线程 js特点 避免死锁
js主线程为单线程 同时又是支持异步操作这种既是单线程又是异步的语言都是基于事件来驱动的
判断同步异步
是否涉及 事件触发 网络请求 定时器操作
同步异步执行:
同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。
当指定的事情完成时,Event Table会将这个函数移入Event Queue。
主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。 上述过程会不断重复,也就是常说的Event Loop(事件循环)。
同步 任务的执行
0.代码没有执行的时候,执行栈为空栈
1.foo函数执行时,创建了一帧,这帧中包含了形参、局部变量(预编译过程),然后把这一帧压入栈中
2.然后执行foo函数内代码,执行bar函数
3.创建新帧,同样有形参、局部变量,压入栈中
4.bar函数执行完毕,弹出栈
5.foo函数执行完毕,弹出栈
6.执行栈为空 执行栈其实相当于js主线程
function outer (ot) {
function inner (it) {
console.log(it);
}
inner(20);
console.log(ot);
}
outer(10);
首先执行完的是内部函数
异步任务执行
setTimeout的等待时间结束后并不是直接执行的而是先推入浏览器 的一个任务队列,在同步队列结束后在依次调用任务队列中的任务。
setTimeout(function(){}, 0)Js主线程中的执行栈为空时,0毫秒实际上也达不到的,根据HTML标准,最低4毫秒。
setInterval是每隔一段时间把任务放到Event Queue之中
function test (num) {
for (var i = 0; I < num; i++) {
console.log(i);
}
}
setTimeout(function () {console.log(‘time’)}, 400);
outer(100000);
//首先js主线程先执行同步任务 将同步任务压入执行栈
//定时器设置400毫秒 进行执行一次 但是由于主任务栈中同步任务未执行完成造成定时器不准