美文网首页
谈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