文章目录
一、什么是EventLoop?
诚如翻译,eventloop就是事件循环,那么javascript究竟为何要采取这种方式进行事件的捕捉循环呢?这同样的使我们值得思考的一个问题。
1.1、javaScript是单线程。
首先我们必须要知道为什么javascript是单线程,在这里同样 阮一峰大神给我们讲解的很清楚 参考 阮一峰:JavaScript 运行机制详解:再谈Event Loop javascript因为什么而是一个单线程的语言呢?我们要了解 从web角度来讲 javascript是基于浏览器去运行的一个语言,而浏览器又是一个面向用户的语言,那么比对用户 我们不得不考虑的一个问题就是:
一个用户在同一时间只能做一件事情,他是不能去做两件事情的,而多线程的理念是什么,就是说在同一时间去干多种不同的事情。但是浏览器缺不行,因为不能说我利用多线程一个线程去干add增加操作,一个线程去做delete删除操作。首先这样去想就是不对的。
包括html5推出的Web Worker,允许创建多个线程,但是其根本上还是不能去操作节点的。
1.2、javaScript的同步、异步理念。
什么是同步?什么是异步?简单的来说:
声明一个变量 执行一个运算就是一个同步
执行一个计时器函数,ajax请求就是一个异步
为什么要有同步异步这个东西?
防止阻塞,而对应的JavaScript就是一个非阻塞的语言,我们试想一下,当去进行一个ajax请求时如果JavaScript是一个同步语言,没有异步这个概念的话,对应如果数据量很庞大,用户等待服务器返还时间需要多久呢?
我们不用过多的去思考同步异步这个问题,简单的来说需要时间去执行的就是异步任务在下方我们也会一一列出。
1.3、浏览器的事件循环(EventLoop)。
执行栈和事件队列
执行栈: 同步代码的执行,按照顺序添加到执行栈中。
事件队列: 异步代码的执行,遇到异步行为不会直接返还执行结果,而是将这个事件行为挂起(注意:挂起的同时也是在运行的),继续向下执行执行栈中的任务。当异步事件返回结果,将它放到事件队列中,被放入事件队列不会立刻执行起回调,而是等待当前执行栈中所有任务都执行完毕,主线程空闲状态,主线程会去查找事件队列中是否有任务,如果有,则取出排在第一位的事件,并把这个事件对应的回调放到执行栈中,然后执行其中的同步代码,当然的如果内部有异步代码,继续的会依照事件队列的执行顺序在执行一遍。
看下图 转自 JavaScript中的Event Loop(事件循环)机制
1.4、异步任务的宏任务、微任务。
宏任务:setTimeout、setInterval等。
微任务:promise、async等。
首先我们要知道为什么要区分异步任务?因为我们要区分优先级
微任务的优先级>宏任务的优先级
为什么?首先我们要知道一个点就是栈的执行机制是先进后出的,但是我们有时不免要出现插队的情况(高优先级先执行,是执行而不是返还先执行不意味着先返还,这个点很重要,不要理解错误。)
在这里也是补充下,下面这张图是没有对同步任务操作进行进栈出栈操作的,但是我们要知道,同步代码执行后,也是会立刻进入到执行栈当中,并且立刻出栈这样一个概念的。(主要也是以下原因:异步任务又分为宏任务和微任务,宏、微任务都是队列,而不是立刻入栈。微、宏任务都会各自创建一个队列,而主线程执行完以后,会优先执行微任务,把微任务全部放到执行栈中执行,最后再从宏任务中取出一个放入执行栈进行执行,执行完后,再取一个,直到执行完所有的宏任务。)所以说同步任务是优先于异步任务去在栈中执行的,因为本身执行栈是一个栈,但同步代码就又马上执行,所以会出现入栈后立即出战的这样一个机制,从而也不会出现同步代码压栈的情况。
一张图带你快速理解宏任务和微任务在任务队列中的区别 转自 深入理解js事件循环机制(浏览器篇):
总结:EventLoop究竟是什么,用于解决什么的?
Event Loop 是一个很重要的概念,指的也就是计算机系统的一种运行机制。JavaScript语言就采用这种机制,来解决单线程运行带来的一些问题。