JavaScript的单线程
早期的网页内容非常简单,单线程足以应付,所以在设计之初,设计者就没考虑使用多线程。另外,JavaScript主要用来处理用户与页面产生的交互,以及操作DOM;如果以多线程的方式来操作DOM,一个线程要求删除该DOM,另一个要求修改DOM样式,那么浏览器该听谁的?这大大增加了程序设计的复杂度,虽然JavaScript是单线程的,可是浏览器内部不是单线程的。你的一些I/O操作、定时器的计时和事件监听(click, keydown…)等都是由浏览器提供的其他线程来完成的。
如果想利用多线程处理一些耗时较长的任务,可以使用HTML5提出的Web Worker。
EventLoop事件循环
主线程总是先执行stack(任务栈)中的代码,任务栈中的如果有异步时间则将异步事件先挂起(网络请求等耗时的I/O操作),继续执行之后的代码,等到异步事件完成之后,然后在主线程执行完stack中的代码之后就会去任务队列中取出对应异步事件的回调函数
定时器
setTimeout(()=>{
console.log('test1');
}, 0);
console.log('test2');
比如上面这段代码,设置了一个延时为0毫秒的定时器,也就是立即执行回调
console.log('test1');
然后执行
console.log('test2');
输入始终是test2--test1,说明主线程是先执行完了setTimeout,console.log('test2')之后才去执行的setTimeout的定时器回调函数输出test1
总结
如果不去深究JS引擎底层如何实现单线程执行并且异步调用的操作,那么我们可以把JS的主线程理解为一个,死循环,这个死循环里面不断地轮询“任务队列”
while(true){
// 轮询任务队列
if(任务队列非空){
// 执行任务
...
}
}