事件循环
事件循环(Event Loop)是现代JavaScript引擎中一个非常核心的概念,尤其在客户端JavaScript(例如浏览器中的JavaScript)和Node.js这样的服务器端JavaScript环境中扮演着关键角色。事件循环机制使得JavaScript能够处理异步操作,同时保持其单线程特性。
JavaScript是单线程的
JavaScript是一种单线程的编程语言,意思就是同一时间段只能做一件事,所有任务都需要排队依次完成;
同步和异步
同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;
异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。
事件循环的工作流程
1.执行栈(Execution Context Stack):• 执行栈是用来存储同步任务的调用记录的地方。每当执行一段新的代码,无论是函数调用还是全局环境,都会有一个新的执行上下文被推入执行栈。
2.• 任务队列(Task Queue):任务队列存放的是所有异步任务的回调函数。当异步任务完成时,它们不会立即执行,而是把相应的回调函数放入任务队列中等待执行。
3.• 定时器与I/O操作:JavaScript的异步操作如setTimeout、setInterval以及文件读写、网络请求等,都会由对应的系统API处理,一旦这些操作完成,就会生成一个事件,这个事件会被加入到任务队列中。
4.• 事件循环:当执行栈为空时,事件循环会检查任务队列,如果队列中有等待执行的任务,则会从中取出第一个任务并将其推入执行栈中执行。由于执行栈一次只能处理一个任务,因此任务队列中的任务会依次被处理,形成了一个循环的过程。
5.• 微任务(Microtasks):除了任务队列外,还有一个微任务队列,它包含了Promise、MutationObserver等一些更优先级的异步操作。微任务会在当前执行栈的同步任务执行完之后立刻执行,但在下一轮事件循环开始之前。整个事件循环的过程会一直持续,直到执行栈为空且任务队列和微任务队列也没有任何待处理的任务为止。这种机制保证了JavaScript的非阻塞性,即使在进行耗时的I/O操作时,也不会阻塞主线程,从而提高了应用程序的响应性和性能。
简单来说,事件循环就是执行栈的同步任务先执行,任务队列的异步任务等待执行栈中的所有任务结束后才去执行,当执行栈中没有任务时会去检查任务队列中是否有等待执行的任务,如果有就将它压入执行栈,在执行栈中执行完毕后再去检查任务队列中是否有等待执行的任务,循环往复直到全部任务执行完毕,这就是事件循环