一、什么叫事件循环
事件循环也就是Event loop, 是JavaScript或Node为解决单线程代码执行不阻塞主进程一种机制,也就是我们所说的异步原理。事件循环负责执行代码、收集和处理事件以及执行队列中的子任务。
二、什么是进程与线程?
进程是计算机中正在运行的程序的一个实例;每个进程都是有独立的内存空间,彼此之间互不影响;是进行资源调度的一个基本单位。类似于安装在手机上的一个应用。
线程是进程中执行的一个实体单位;复杂应用中一个进程通常包括多个线程,用于同时执行不同的任务,例如游戏应用中,有的线程负责网络通讯,有的线程负责游戏交互和渲染等。类似应用中的很多任务线。
三、什么是线程阻塞?
JavaScript的一大特点就是单线程,也就是说,同一个时间只能做一件事。任何在主线程上执行的长时间运行的任务(例如复杂的计算、大量的循环等)都会导致执行栈无法处理其他事件,包括用户输入、UI 更新和异步回调。这种情况下,浏览器可能会出现卡顿或无响应的情况。
四、JS如何解决线程阻塞?
使用异步编程是解决线程阻塞的主要方法之一。通过将耗时的任务放入异步回调中,可以让主线程继续处理其他任务。如下图:
1、同步任务: 在主线程上排队执行的任务只有前一个任务执行完毕,才能执行后一个任务,形成一个执行栈。(promise是同步任务)
2、异步任务: 不进入主线程,而是进入任务队列,当主线程中的任务执行完毕,就从任务队列中取出任务放进主线程中来进行执行。在异步模式下,创建异步任务主要分为宏任务与微任务两种。
(1) 宏任务:是由宿主(浏览器、Node)发起的,而微任务由 JS 自身发起。
宏任务(Macrotask)包括:
1. 整体代码script;
2. 定时器任务: 如setTimeout、setInterval、setImmediate (NodeJS独有);
3. I/O操作: 网络请求,文件读写;
4. 渲染任务:dom渲染,当浏览器需要重绘或重新布局时触发的任务;
5. 异步ajax等;
6. 用户交互任务:例如点击事件、输入事件等与用户交互的相关任务;
7. 请求动画帧任务:通过requestAnimationFrame()方法设置的任务,用于在每一帧进行绘画或动画操作;
这些任务都是比较耗时的操作,在事件循环中被视为宏任务,需要等待一定时间或特定的触发条件才会执行。
宏任务的执行顺序:setImmediate --> setTimeout --> setInterval --> i/o操作 --> 异步ajax。