【JavaScript】31_BOM定时器与事件循环

59 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第33天,点击查看活动详情

5、定时器

通过定时器,可以使代码在指定时间后执行

  • 设置定时器的方式有两种:

setTimeout()

  • 参数:

    1. 回调函数(要执行的代码)
    2. 间隔的时间(毫秒)
  • 关闭定时器

clearTimeout()

setInterval()

每间隔一段时间代码就会执行一次

  • 参数:

    1. 回调函数(要执行的代码)
    2. 间隔的时间(毫秒)
  • 关闭定时器

clearInterval()

 <body>
     <h1 id="num"></h1>
 ​
     <script>
         // const timer = setTimeout(()=>{
         //     alert('我是定时器中的代码')
         // },3000)//只执行一次
 ​
         // clearTimeout(timer)
 ​
         const numH1 = document.getElementById('num')
 ​
         let num = 0
         const timer = setInterval(() => {
             num++
             numH1.textContent = num
 ​
             if(num === 200){
                 clearInterval(timer)
             }
         },3000)
     </script>
 </body>

6、深入理解定时器

定时器的本质

就是在指定时间后将函数添加到消息队列中

setInterval() 没间隔一段时间就将函数添加到消息队列中

但是如果函数执行的速度比较慢,它是无法确保每次执行的间隔都是一样的

     <script>
         console.time()
 ​
         setTimeout(function(){
             console.timeEnd()
             console.log('定时器执行了')
         },3000)
 ​
         //使程序卡6s
         const begin = Date.now()
         while(Date.now() - begin < 6000){}
 ​
 ​
         console.time("间隔")
         setInterval(function(){
             console.timeEnd('间隔')
 ​
             console.log('定时器执行了~')
             alert('定时器执行~')
 ​
             console.time('间隔')
         },3000)
 ​
 ​
         /* 
             希望可以确保函数每次执行都有相同间隔
         */
 ​
         // console.time("间隔")
         // setTimeout(function fn() {
         //     console.timeEnd("间隔")
         //     alert("哈哈")
 ​
         //     console.time("间隔")
         //     // 在setTimeout的回调函数的最后,在调用一个setTimeout
         //     setTimeout(fn, 3000)
         // }, 3000)
 ​
 ​
         setTimeout(()=>{
             console.log(11111)
         }, 0)
 ​
         console.log(222222)
     </script>

7、事件循环

事件循环(event loop)

  • 函数在每次执行时,都会产生一个执行环境

  • 执行环境负责存储函数执行时产生的一切数据

  • 问题:函数的执行环境要存储到哪里呢?

    • 函数的执行环境存储到了一个叫做调用栈的地方
    • 栈,是一种数据结构,特点 后进先出
    • 队列,是一种数据结构,特点 先进先出

调用栈(call stack)

 - 调用栈负责存储函数的执行环境
     - 当一个函数被调用时,它的执行环境会作为一个栈帧
     插入到调用栈的栈顶,函数执行完毕其栈帧会自动从栈中弹出
     
     ```html
         <script>
             function fn(){
                 let a = 10
                 let b = 20
     
                 function fn2(){
                     console.log('fn2')
                 }
     
                 fn2()
     
                 console.log('fn~')
             }
     
             fn()
     
             console.log(1111)
         </script>
     ```

image.png

  • 队列,是一种数据结构,特点 先进先出

消息队列

  • 消息队列负责存储将要执行的函数

  • 当我们触发一个事件时,其响应函数并不是直接就添加到调用栈中的。

    • 因为调用栈中有可能会存在一些还没有执行完的代码
  • 事件触发后,JS引擎是将事件响应函数插入到消息队列中排队

 <body>
     <button id="btn">点我一下</button>
     <button id="btn02">点我一下2</button>
 ​
     <script>
         function fn(){
             let a = 10
             let b = 20
 ​
             function fn2(){
                 console.log('fn2')
             }
 ​
             fn2()
 ​
             console.log('fn~')
         }
 ​
         fn()
 ​
         console.log(1111)
 ​
         const btn = document.getElementById("btn")
         const btn02 = document.getElementById("btn02")
 ​
         btn.onclick = function(){
             alert(1111)
             const begin = Date.now()
 ​
             while(Date.now() - begin < 3000){
             }
         }
 ​
         btn02.onclick = function () {
             alert(2222)
         }
     </script>
 </body>