1.知识储备
js是一门单线程语言,即同一时间只能执行一个任务;
-
回调函数
-
队列(queue)
队列是一种 FIFO (First In First Out )的数据结构,特点是先进先出;
-
栈(stack)
栈是一种LIFO (Last In First Out)数据结构,即先进后出;
-
事件表格(event table)
Event Table 可以理解为一种 事件---回调函数 的对应表
-
事件队列 (event queue)
就是 回调函数 队列,所以也叫callback queue;
当event table中的事件被触发,事件对应的回调函数就会被push进这个event queue,然后等待被主线程调用执行;
-
执行栈(也叫调用栈) call stack
当我们调用一个方法时,js会生成一个与这个方法相对应的执行环境,也叫做执行上下文。这个执行环境中存在着这个方法的私有作用域,参数,this对象等等。因为js 是单线程的,同一时间只能执行一个方法,所以当一系列的方法被调用时,js会先解析这些方法,把其中的同步任务按执行顺序排列到一个地方,这个地方叫做执行栈。Event loop会一直检查call stack 中是否有函数需要执行,如果有,就从栈顶依次执行。同时,如果在过程中发现其他函数,继续入栈然后执行。
2.JS的运行机制
所有同步任务都在主线程上执行,形成一个执行栈;
除了主线程外,还存在一个或多个‘任务队列’,用来存放异步函数;
一旦‘执行栈’中的所有同步任务执行完毕,系统都会读取 ‘任务队列’ 中有没有任务,如果有,就读取执行,一直循环 读取-执行 操作
3.JS中有两种异步任务
宏任务
-
微任务
宏任务是由宿主发起的,而微任务由JavaScript自身发起。
注意: 微任务永远在宏任务之前执行
4.Event Loop具体执行步骤
注意:Promise中,then中的才是异步的微任务,主体方法是同步任务
Event Loop的事件执行顺序图:
上图可知:
一轮事件轮询中,微任务永远在宏任务之前执行(如果有微任务的话)
-
总结:
先处理主线程上的同步任务,在执行异步任务,而异步任务分为 宏任务和微任务,其中微任务永远在宏任务之前执行。
同步任务--(微任务--宏任务)-->下一轮...
5.具体例子
例子二(复杂)
解析如下: