美文网首页
JS:事件循环机制(Event Loops)

JS:事件循环机制(Event Loops)

作者: limengzhe | 来源:发表于2021-04-06 18:33 被阅读0次
  1. 在深入了解事件循环之前,我们不妨先做道题

    思考下面代码的执行结果

    setTimeout(() => {
      console.log(1)
    }, 0)
    
    new Promise((resolve, reject) => {
      console.log(2)
      resolve(3)
    }).then(val => {
      console.log(val)
    })
    
    console.log(4)
    

    输出结果是:

    2
    4
    3
    1
    

    你做对了吗?这里我们不禁要问:

    • 为什么 setTimeout() 设定的时间是 0 毫秒,但 1 却是在最后输出的?

    • 为什么 Promise.then() 的回调函数会在 4 输出之后执行,而不是在 2 之后?

    其实,在 JavaScript 中,代码的执行顺序并不是完全按照它们的书写顺序,而是取决于它们在事件循环中的顺序。

  2. 什么是事件循环?

    事件循环,即 Event Loops。用于协调事件、用户交互、JavaScript 脚本、DOM 渲染、网络请求等等的执行顺序问题。

    一个遵循 ECMAScript 标准的代理(浏览器或 JS 引擎)也必须遵循事件循环机制。

    事件循环是由一个或以上的任务队列组成的。

  3. 什么是任务队列?

    任务队列,即 Task Queues,是一组任务的集合(Sets)。

    由于 JavaScript 是 单线程 语言,所以在 JS 中所有的任务都需要排队执行,这些任务共同组成了任务队列,依次排队执行的过程,形成一个执行栈(Execution Context Stack)

    在任务队列中最先执行是同步任务。

  4. 什么是同步任务?

    同步任务,即 Synchronous Task。就是当上一个任务执行完成后,接下来可以立即执行的任务。它们在主线程上依次排队执行,直到清空。

    比如,下面代码中的 for()console.log() 将会依次执行,最终输出 0 1 2 done

    for (let i = 0; i < 3; i++) {
      console.log(i)
    }
    
    console.log('done')
    

    与同步任务相比,异步任务的执行充满了不确定性。

  5. 什么是异步任务?

    异步任务,即 Asynchronous Task。就是需要等待被通知才以执行的任务。也就是说,它们不会直接进入主线程执行,而是进入到微任务队列或下一次事件循环中的任务队列进行等待。

    常见的异步任务有:

    • XMLHttpRequest()

    • Promise.then()Promise.catch()Promise.finally()

    • setTimeout()setInterval()

    等待,就意味着不确定性。比如,XMLHttpRequest() 等待服务器响应,Promise.then() 等待 resolve()setTimeout() 等待时间。

    所以虽然都是异步任务,它们的执行的顺序仍然会有所区别。因此,我们将它们分为宏任务微任务

  6. 什么是宏任务?

    宏任务,即 MacroTask。就是指进入任务队列的任务。比如:

    由于当前任务队列已经处于执行状态,所以任务队列中遇到的宏任务将进入到下一次事件循环的任务队列,而微任务则会被放入到本次事件循环的微任务队列中。

  7. 什么是微任务?

    微任务,即 Microtask 或 Jobs。每次事件循环都会有一个初始为空的微任务队列。常见的微任务有:

    • Promise.then()Promise.catch()Promise.finally()

    • MutationObserver()(浏览器环境)

    • process.nextTick()(Node.js 环境)

  8. 测试题

    看到这里,JavaScript 的事件循环机制差不多就解释完了,涉及到了同步任务、异步任务、宏任务和微任务以及它们之间的关系。

    下面有几道测试题,同学们可以测试一下自己的理解程度:

    • 简单

      setTimeout(() => {
        console.log(1)
      }, 0)
      
      for (let i = 2; i <= 3; i++) {
        console.log(i)
      }
      
      console.log(4)
      
      setTimeout(() => {
        console.log(5)
      }, 0)
      
      for (let i = 6; i <= 7; i++) {
        console.log(i)
      }
      
      console.log(8)
      
    • 普通

      console.log(1)
      
      async function async1() {
        await async2()
        console.log(2)
      }
      
      async function async2() {
        console.log(3)
      }
      
      async1()
      
      setTimeout(() => {
        console.log(4)
      }, 0)
      
      new Promise(resolve => {
        console.log(5)
        resolve()
      })
        .then(() => {
          console.log(6)
        })
        .then(() => {
          console.log(7)
        })
      
      console.log(8)
      
    • 困难

      console.log(1)
      
      function a() {
        return new Promise(resolve => {
          console.log(2)
          setTimeout(() => {
            resolve()
            console.log(3)
          }, 0)
        })
      }
      
      a().then(() => {
        console.log(4)
      })
      

参考资料:

相关文章

  • JS:事件循环机制(Event Loops)

    在深入了解事件循环之前,我们不妨先做道题思考下面代码的执行结果setTimeout(() => { consol...

  • js高级进阶

    1.Object.definePorperty 2.js的执行机制 js是单线程的 js的事件循环(Event L...

  • 20211021

    1、js里的事件循环机制(event loop)答:js事件循环中有异步队列有两种:宏任务队列(macro)和微任...

  • iOS RunLoop由浅入深

    Event Loop Event Loop事件循环机制,如javascript的事件循环,以及依赖其的nodejs...

  • Js 的多宿主时代

    之前有写过一篇文章 Js运行机制深层剖析,主要讲的是 Js 的事件循环机制 (Event Loop),从现在的眼光...

  • 成长(10/2000)——面试题合集7

    事件循环机制event-loop 事件循环机制由三部分组成:调用栈、消息队列和微任务队列。 event-loop开...

  • Js事件循环(Event Loop)机制

    前言 Event Loop是计算机系统的一种运行机制,是个很重要的概念。而Javascript用这种机制来解决单线...

  • JS事件循环机制(Event Loop)

    一、3个组成 1、调用栈(call stack)2、消息队列(message queue)3、微任务队列(micr...

  • JS事件循环机制Event Loop

    执行顺序 微任务——DOM渲染——宏任务 微任务 Promise.thenObject.observeMutati...

  • JavaScript eventLoop tasks & mi

    首先,JavaScript是单线程的,用事件循环的机制来保证系统的正常运行。 JS 的 event loop 执行...

网友评论

      本文标题:JS:事件循环机制(Event Loops)

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