JavaScript中的矛与盾--单线程和异步

2019-03-03  本文已影响0人  一线码农

JavaScript的单线程

早期的网页内容非常简单,单线程足以应付,所以在设计之初,设计者就没考虑使用多线程。另外,JavaScript主要用来处理用户与页面产生的交互,以及操作DOM;如果以多线程的方式来操作DOM,一个线程要求删除该DOM,另一个要求修改DOM样式,那么浏览器该听谁的?这大大增加了程序设计的复杂度,虽然JavaScript是单线程的,可是浏览器内部不是单线程的。你的一些I/O操作、定时器的计时和事件监听(click, keydown…)等都是由浏览器提供的其他线程来完成的。
如果想利用多线程处理一些耗时较长的任务,可以使用HTML5提出的Web Worker。

EventLoop事件循环

图片来源

EventLoop
主线程总是先执行stack(任务栈)中的代码,任务栈中的如果有异步时间则将异步事件先挂起(网络请求等耗时的I/O操作),继续执行之后的代码,等到异步事件完成之后,然后在主线程执行完stack中的代码之后就会去任务队列中取出对应异步事件的回调函数

定时器

setTimeout(()=>{
   console.log('test1');
}, 0);
console.log('test2');

比如上面这段代码,设置了一个延时为0毫秒的定时器,也就是立即执行回调

console.log('test1');

然后执行

console.log('test2');
屏幕快照 2019-03-02 下午7.05.06.png

输入始终是test2--test1,说明主线程是先执行完了setTimeout,console.log('test2')之后才去执行的setTimeout的定时器回调函数输出test1

总结

如果不去深究JS引擎底层如何实现单线程执行并且异步调用的操作,那么我们可以把JS的主线程理解为一个,死循环,这个死循环里面不断地轮询“任务队列”

while(true){
  // 轮询任务队列
  if(任务队列非空){
    // 执行任务
    ...
  }
}
上一篇 下一篇

猜你喜欢

热点阅读