美文网首页
谈Event Loop

谈Event Loop

作者: 转移到CSDN名字丹丹的小跟班 | 来源:发表于2021-03-24 15:57 被阅读0次

本文内容主要来自阮一峰网络日志

一、为什么JavaScript是单线程?

JavaScript这门语言最大的特点之一就是他的单线程,也就是说,在同一时间只能做一件事。

为什么不实行多线程
这其实跟他的用途有关。作为一种浏览器的地脚本语言,他的主要作用就是实现用户互动,以及操作DOM。这也就决定了它地单线程特性。假定js同时有两个线程,一个线程需要删除内容,一个线程需要增加内容,那就不知道以哪个为准。

所以,为了避免复杂性,单线程就成了js这门语言的核心特征,将来应该也不会改变。

为了利用多核CPU的计算能力,HTML5提出了Web Worker标准,允许js脚本创建多个线程,但是子线程完全受主线程控制,且不得操作。所以本质这个新标准并没有改变js的单线程性质。

二. 任务队列

js的单线程就意味着所以的任务执行都需要排队。前一个任务执行完成后才能执行后一个任务。如果前面任务执行时间过长,那么后面的任务不得不一直等待。

于是设计者们将所有任务分为了两种,同步任务与异步任务。
同步任务指的是在主线程执行的任务,也就是需要等待前面任务执行完成才能执行后面任务的机制。
异步任务指的是不进入主线程,而进入任务队列,只有等待任务队列通知主线程某个任务可以执行了,该任务才会进入主线程。
具体异步执行机制如下:

  1. 所有同步任务都在主线程执行,形成一个执行栈。
  2. 主线程之外还存在一个任务队列,只要异步任务有了运行结果,就在任务队列中放置一个事件。
  3. 一旦所有的同步任务执行完成后,系统就会读取任务队列,那些异步任务于是结束等待状态,进入执行栈,开始执行。
  4. 主线程不断重读以上过程。
三. 计时器

使用计时器可以将代码手动放入任务队列里。

setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,也就是说,尽可能早得执行。它在"任务队列"的尾部添加一个事件,因此要等到同步任务和"任务队列"现有的事件都处理完,才会得到执行。

HTML5标准规定了setTimeout()的第二个参数的最小值(最短间隔),不得低于4毫秒,如果低于这个值,就会自动增加。在此之前,老版本的浏览器都将最短间隔设为10毫秒。另外,对于那些DOM的变动(尤其是涉及页面重新渲染的部分),通常不会立即执行,而是每16毫秒执行一次。这时使用requestAnimationFrame()的效果要好于setTimeout()。

需要注意的是,setTimeout()只是将事件插入了"任务队列",必须等到当前代码(执行栈)执行完,主线程才会去执行它指定的回调函数。要是当前代码耗时很长,有可能要等很久,所以并没有办法保证,回调函数一定会在setTimeout()指定的时间执行。

相关文章

网友评论

      本文标题:谈Event Loop

      本文链接:https://www.haomeiwen.com/subject/qtqbqltx.html