js--setTimeout与setInterval

前置知识点
  • 首先,JS是单线程的,同一时间只会执行一段JS代码。
  • 不过,浏览器是多线程的,但这也不意味着可以模拟JS的多线程。
  • 浏览器中至少有3个常驻线程:
    • JS引擎(执行JS代码)
    • GUI渲染线程:当界面需要重绘(Repaint)或由于某种操作引发回流(Reflow)时,GUI线程就会执行。

    补充:JS引擎和GUI渲染线程是互斥的,当JavaScript引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到JavaScript引擎空闲时立即被执行。

    • 浏览器事件触发线程:当一个事件被触发时该线程会把事件添加到待处理队列的队尾,等待JavaScript引擎的处理。
      • 这些事件可来自JavaScript引擎当前执行的代码块如setTimeout、也可来自浏览器内核的其他线程如鼠标点击、Ajax异步请求等
  • 事件循环模型: 每次有事件发生时,事件触发线程将事件放入任务队列,等到执行引擎在主线程方法(也可以说是同步任务)执行完毕,到达空闲状态时,会从任务队列中顺序获取任务来执行(这里的是异步任务),这一过程是一个不断循环的过程,称为事件循环模型。

setTimeout(fn,xx)

  • 当在主体代码中执行到setTimeout函数时,浏览器会开启一个定时器线程,当过了指定的时间间隔以后,会向任务队列插入任务,即使间隔时间设置为0,也还是要放入任务队列,等待所有主体任务完成以后,执行线程再从任务队列中取出任务来执行。

setInterval(fn,xx)

  • 大致部分同上,只是有一点需要注意,有时候会因主体部分代码执行占用了处理器时间,导致事件线程第n次向任务队列插入任务时,第n-1次的任务还没被执行,此时会放弃第n次插入。
    • 因为js有规定:

      为了确保定时器代码插入到队列总的最小间隔为指定时间。当使用setInterval()时,仅当没有该定时器的任何其他代码实例时,才能将定时器代码添加到代码队列中。

你可能感兴趣的:(js--setTimeout与setInterval)