Js 的事件循环(Event Loop)机制以及实例讲解

作者 : 开心源码 本文共1687个字,预计阅读时间需要5分钟 发布时间: 2022-05-11 共66人阅读

前言

大家都知道js是单线程的脚本语言,在同一时间,只可以做同一件事,为了协调事件、使用户交互、脚本、UI渲染和网络解决等行为,防止主线程阻塞,Event Loop方案应运而生…为什么js是单线程?

js作为主要运行在浏览器的脚本语言,js主要使用途之一是操作DOM。

在js高程中举过一个栗子,假如js同时有两个线程,同时对同一个dom进行操作,这时浏览器应该听哪个线程的,如何判断优先级?

为了避免这种问题,js必需是一门单线程语言,并且在未来这个特点也不会改变。


执行栈与任务队列

由于js是单线程语言,当遇到异步任务(如ajax操作等)时,不可可以一直等待异步完成,再继续往下执行,在这期间浏览器是空闲状态,显而易见这会导致巨大的资源白费。

执行栈

当执行某个函数、使用户点击一次鼠标,Ajax完成,一个图片加载完成等事件发生时,只需指定过回调函数,这些事件发生时就会进入执行栈队列中,等待主线程读取,遵循先进先出准则。

主线程

要明确的一点是,主线程跟执行栈是不同概念,主线程规定现在执行执行栈中的哪个事件。

主线程循环:即主线程会不停的从执行栈中读取事件,会执行完所有栈中的同步代码。

当遇到一个异步事件后,并不会一直等待异步事件返回结果,而是会将这个事件挂在与执行栈不同的队列中,我们称之为任务队列(Task Queue)。

当主线程将执行栈中所有的代码执行完之后,主线程将会去查看任务队列能否有任务。假如有,那么主线程会依次执行那些任务队列中的回调函数。

不太了解的话,能运行一下下面的代码,或者者点击一下这个demo

结果是当a、b、c函数都执行完成之后,三个setTimeout才会依次执行。

pre class=”brush:js;toolbar:false”>let a = () => { setTimeout(() => { console.log('任务队列函数1') }, 0) for (let i = 0; i { setTimeout(() => { console.log('任务队列函数2') }, 0) for (let i = 0; i { setTimeout(() => { console.log('任务队列函数3') }, 0) for (let i = 0; i < 5000; i++) { console.log('c的for循环') } console.log('c事件执行完')}a();b();c();// 当a、b、c函数都执行完成之后,三个setTimeout才会依次执行


js 异步执行的运行机制。

  1. 所有任务都在主线程上执行,形成一个执行栈。
  2. 主线程之外,还存在一个”任务队列”(task queue)。只需异步任务有了运行结果,就在”任务队列”之中放置一个事件。
  3. 一旦”执行栈”中的所有同步任务执行完毕,系统就会读取”任务队列”。那些对应的异步任务,结束等待状态,进入执行栈并开始执行。
  4. 主线程不断重复上面的第三步

宏任务与微任务:

异步任务分为 宏任务(macrotask) 与 微任务 (microtask),不同的API注册的任务会依次进入自身对应的队列中,而后等待 Event Loop 将它们依次压入执行栈中执行。

宏任务(macrotask):

script(整体代码)、setTimeout、setInterval、UI 渲染、 I/O、postMessage、 MessageChannel、setImmediate(Node.js 环境)

微任务(microtask):

Promise、 MutaionObserver、process.nextTick(Node.js环境)

Event Loop(事件循环):

Event Loop(事件循环)中,每一次循环称为 tick, 每一次tick的任务如下:

  • 执行栈选择最先进入队列的宏任务(通常是script整体代码),假如有则执行
  • 检查能否存在 Microtask,假如存在则不停的执行,直至清空 microtask 队列
  • 升级render(每一次事件循环,浏览器都可可以会去升级渲染)
  • 重复以上步骤

宏任务 > 所有微任务 > 宏任务,如下图所示:

Js 的事件循环(Event Loop)机制以及实例讲解

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Js 的事件循环(Event Loop)机制以及实例讲解

发表回复