最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 前端面试之JavaScript基础(七)—— Event Loop

    正文概述 掘金(馒头君)   2021-03-06   517

    事件循环(Event Loop)机制是异步编程的关键知识点,理解该机制有利于我们更好的理解和书写异步代码。我们都知道 JavaScript 是基于 单线程 设计的,当我们的代码都是同步执行时就会很容易产生 阻塞。此时,为了避免阻塞的发生就诞生了 异步编程 ,为了支撑异步编程代码运作就产生了 事件循环 机制。接下来,我们通过一张图来了解事件循环究竟是什么: 前端面试之JavaScript基础(七)——  Event Loop 上图展示的是 JavaScript 的基础线程架构,运行时 主线程 会从维护异步事件的 消息队列 中取出任务并执行。执行时有的任务是从网络上下载资源,有的任务是文件读取,当这些任务又需要异步处理时就会被包装成新的任务再次加入消息队列,如此循环往复的取出并执行的工作机制就被称为 事件循环机制

    宏任务与微任务

    当我们了解了事件循环机制后,我们就来看看与其有紧密联系的概念 宏任务微任务

    • 宏任务:在消息队列中等待被主线程执行的事件
    • 微任务:一个需要异步执行的事件,执行时机是在主任务执行结束之后、当前宏任务结束之前。

    宏任务

    function foo() {
      console.log('success')
    }
    
    setTimeout(foo, 1000)
    

    产生宏任务的典型代表就是 setTimeout ,我们通过分析上述这段代码来看看宏任务是什么及其执行时机。 前端面试之JavaScript基础(七)——  Event Loop 从图中可以看出,每产生一个宏任务就会被加入消息队列的尾部,主线程会不断的从消息队列的头部位置取出宏任务执行。

    微任务

    主线程执行宏任务有一个比较明显的缺点,那就是时间颗粒度的把控太粗糙,无法胜任对精度和实时性较高的场景。当消息队列当中有一个任务执行时间过长时,就会影响到排在其后面的事件,为了解决这个不可控的情况就引入了微任务的概念。

    Promise.resolve 可以生成一个微任务,接下来我们就用这个方法结合 主线程消息队列调用栈 来了解微任务。

    function foo() {
      console.log('foo')
      Promise.resolve().then(() => console.log('微任务 - foo'))
      setTimeout(() => console.log('宏任务 - foo'), 0)
    }
    
    foo()
    
    console.log('global')
    Promise.resolve().then(() => console.log('微任务 - global'))
    setTimeout(() => console.log('宏任务 - global'), 0)
    

    在这段代码中,包含了通过 setTimeout 产生的宏任务和 Promise.resolve 创建的微任务,它的最终打印结果是:

    foo
    global
    微任务 - foo
    微任务 - global
    宏任务 - foo
    宏任务 - global
    

    接下来我们通过执行过程来分析微任务的执行,请看下图: 前端面试之JavaScript基础(七)——  Event Loop 上图展示了一部分执行过程,从图中可以看到除了存放宏任务的消息队列外还多了一个 微任务队列。JavaScript 引擎在工作时会在当前执行的主任务当中维护一个微任务队列,当该任务 快要执行结束时 就会将微任务队列当中的任务依次取出并 全部执行完毕 再执行下一个宏任务。

    完整的执行过程如下:

    1. 主任务执行时,首先调用 foo 函数执行同步代码 console.log('foo')
    2. Promise.resolve 执行会向微任务队列中加入执行 console.log('微任务 - foo') 的事件;
    3. setTimeout 执行会向消息队列中加入执行 console.log('宏任务 - foo') 的事件;
    4. 主任务继续执行,执行同步代码 console.log('global')
    5. Promise.resolve 执行会向微任务队列中加入执行 console.log('微任务 - global') 的事件;
    6. setTimeout 执行会向消息队列中加入执行 console.log('宏任务 - global') 的事件;
    7. 此时主任务已经快执行结束,这时引擎会依次执行微任务队列当中的内容,直到清空该队列就结束当前任务;
    8. 主线程从消息队列当中继续取下一个任务执行。

    小结

    今天我们讲了事件循环机制和宏任务与微任务的概念,总结一下:

    • 事件循环机制是为主线程调度异步任务的一种机制,主线程会循环的从消息队列中取出任务并执行,直至消息队列清空便会挂起,消息队列当中出现新任务有回继续执行。
    • 宏任务是消息队列当中待执行的任务,宏任务主要有 setTimeout/setInterval、IO 事件。
    • 微任务是为了解决宏任务的时间颗粒度太粗糙而产生的,它会在当前主任务要结束后,宏任务结束前全部执行,微任务主要有 Promise、MutationObserver。

    起源地下载网 » 前端面试之JavaScript基础(七)—— Event Loop

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元