事件循环-宏任务-微任务

  • Post author:
  • Post category:其他




概述

  • Javascript是一门单线程的脚本语言
  • 时间循环(EventLoop)是JavaScript的运行机制

首先我们先看一下以下代码

setTimeout(function() {
		console.log('s1')
	}, 0)

setTimeout(function() {
		console.log('s2')
		Promise.resolve().then(() => {
			console.log('s2 - promise')
		})
}, 0)
new Promise(function executor(resolve) {
    console.log('p1')
    resolve()
    console.log('p2')
}).then(function() {
    console.log('promise then')
})
console.log('end')


在公布结果之前先分析一下以上代码的知识点有哪些?


1.宏任务 2.微任务3.事件循环



事件循环(EventLoop)

主线程从”

任务队列

“中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)。

  1. JS程序进入JS引擎线程,函数入栈,遇到同步代码就顺序执行执行,遇到异步代码时,把异步代码任务抛给WebAPIs执行,然后继续执行接下来的同步代码,直到栈为空。
  2. WebAPIs执行异步任务,当执行完一个异步任务就将其对应的回调函数放入任务队列(Callback Queue)中等待。(WebAPIs是由C++实现的浏览器创建的线程,处理Dom事件,http请求,定时器任务等异步任务)
  3. 当执行调用栈(Call Stack)为空时,从回调队列(Callback Queue)中取出对队首的任务放入函数栈中执行,消费完出栈。
  4. 事件循环机制不断的循环上面步骤,直到队列为空。

在这里插入图片描述



任务队列

  • JavaScript有一个基于事件循环的并发模型,事件循环负责执行代码、收集和处理事件以及执行队列中的子任务。



宏任务

宏任务是JavaScript中最原始的异步任务,包括

setTimeout、setInterVal、AJAX

等,在代码执行环境中按照同步代 码的顺序,逐个进入工作线程挂起,再按照异步任务到达的时间节点,逐个进入异步任务队列,最终按照队列中的 顺序进入函数执行栈进行执行。



微任务

微任务是随着ECMA标准升级提出的新的异步任务,微任务在异步任务队列的基础上增加了【微任务】的概念,每 一个宏任务执行前,程序会先检测中是否有当次事件循环未执行的微任务,优先清空本次的微任务后,再执行下一 个宏任务,每一个宏任务内部可注册当次任务的微任务队列,再下一个宏任务执行前运行,微任务也是按照进入队 列的顺序执行的。


Promise.then catch finally

就为微任务

  • 上边的代码执行结果为
  1. p1
  2. p2
  3. end
  4. promise then
  5. s1
  6. s2
  7. s2 – promise


分析
  1. 从上往下来看

    setTimeOut

    为宏任务 放到栈里面不执行 ,

    new Promise

    为同步代码块先执行

    then

    为微任务不执行

console.log(‘p1’)

console.log(‘p2’)

console.log(‘end’)

  1. 同步代码执行完成后我们发现既有微任务和宏任务,微任务和宏任务同时存在则优选执行微任务。

console.log(‘promise then’)

  1. 执行宏任务每一个宏任务是单独的,如果宏任务中既有宏任务又有微任务也有同步代码,我们需要按照

    同步代码>微任务>宏任务

    的执行顺序

console.log(‘s1’)

console.log(‘s2’)

console.log(‘s2 – promise’)

参考链接:https://www.ruanyifeng.com/blog/2014/10/event-loop.html



版权声明:本文为weixin_44389562原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。