概述:单线程 任务队列 同步异步
console.log(1)//console.log() 同步任务
setTimeout(function (){//setTimeout 异步任务,挂起
console.log(2)
}, 0)
console.log(3)//同步任务执行完毕才执行异步任务
//执行结果
1
3
2
如何理解JS 的单线程
JS是单线程,也就是在同一个时间只做一件事情。
什么是任务队列
单线程任务队列有优先顺序,在JS运行机制的执行过程中,优先执行同步任务,同步任务执行完成之后才响应(执行)异步任务。
console.log('A')
while (true){// while 是同步任务,满足条件会不断循环,不会执行后续的同步任务
}
console.log('B')
//执行结果
A
console.log('A')
setTimeout(function () {
console.log('B')//同步任务没有执行完毕,不会执行异步任务
}, 0)
while (true){// while 是同步任务,满足条件会不断循环,不会执行后续的同步任务
}
//执行结果
A
for(var i = 0; i < 4; i++){//for 循环是同步任务
setTimeout(function (){//setTimeout 是异步任务,到了指定的时间才会把setTimeout 放到异步任务队列,这时for循环已经完成所有的循环操作,异步任务才会被一一放置到异步队列
console.log(1)
}, 1000)
}
//执行结果
4
4
4
4
Event Loop(以setTimeout、setInterval 为例)
浏览器的JS引擎遇到setTimeout、setInterval 等异步任务,识别其为异步任务后,会将其从运行栈拿走。同步任务执行完之后,timer模块计算到时间已到(最新浏览器最小时间为4毫秒,原为10毫秒。也就是小于4毫秒按4毫秒算),会将其放入异步队列中。JS引擎发现运行栈已没有要执行的同步任务会去异步任务队列中读异步任务,读取到之后放入运行栈,此时setTimeout里的函数体就变成了运行栈里的同步任务并被执行,执行完之后运行栈为空,继续监听异步任务队列是否有异步任务,若有继续执行,以此类推便为 Event Loop.
异步任务都有哪些
1、setTimeout 和 SetInterval:参考上述Event Loop
2、Dom 事件
用 addEventListener 注册一个Event 类型的事件,浏览器的事件处理模块接收事件注册,当事件被触发,监听 GUI 线程,浏览器的事件处理模块把注册的函数体放入异步任务队列,如果此时运行栈中是空的,去异步任务队列读取该异步任务放入同步队列并执行。如:浏览器假死
3、ES6 中的 Promise