美文网首页
js EventLoop、宏任务和微任务

js EventLoop、宏任务和微任务

作者: 咸鱼不咸_123 | 来源:发表于2022-04-06 14:40 被阅读0次

1.javascript是单线程的语言

javascript是一门单线程执行的编程语言。也就是说,同一时间只能做一件事情。

如下:如果有多个任务要执行,执行其他任务时,其他任务都要进行等待

52.png

1.1 单线程执行任务队列的问题

如果前一个任务非常耗时,则后续的任务不得不一直等待,从而导致程序假死的问题。

2.同步任务和异步任务

为了防止某个耗时任务导致程序假死的问题,javascript把待执行的任务分为了两类。

  • 同步任务
    • 又叫做 非耗时任务,指的是在主线程上排队执行的那些任务
    • 只有前一个任务执行完毕,才能执行后一个任务
  • 异步任务
    • 又叫做非耗时任务,异步任务由javascript委托给宿主环境进行执行
    • 当异步任务执行完成之后,会通知javascript主线程执行异步任务的回调函数

2.1 同步任务和异步任务的执行过程

53.png
  • 同步任务由javascript主线程次序执行
  • 异步任务委托给宿主环境执行
  • 已完成的异步任务对应的回调函数,会被加入到任务队列中等待执行
  • javascript主线程的执行栈被清空后,会读取任务队列中的回调函数,次序执行。
  • javascript主线程不断重复上面的第4步

js的主线程会从自己的执行栈中去执行栈中的所有任务,当发现任务是同步任务时,js会自己进行执行。如果是异步任务,会委托给宿主环境执行。当js发现自己的执行栈中被执行完后,会从任务队列中按顺序把对应的回调函数取出来放入栈中,按顺序执行。

3.EventLoop的基本概念

javascript主线程从“任务队列”中读取异步任务回调函数,放到执行栈中依次执行。这个过程是循环不断的,所以整个的这种运行机制又称为EventLoop(事件循环)。

3.1 结合EventLoop分析输出顺序

import thenFs from "then-fs";

console.log("A");
thenFs.readFile("./studyPrommise/files/1.txt","utf8").then(res=>{console.log("B");})


setTimeout(()=>{
  console.log("C");
},0)

console.log("D");
  • 最终的结果是 A D C B
  • 因为主线程上只有A和D,是同步任务,所以会依次执行,而B、C是异步任务让js委托给宿主环境执行。
  • 然后定时器,只是延时了0秒,所以就会让宿主环境立即执行,然后返回一个回调函数,等主线程空闲时执行。

4.宏任务和微任务

javascript对异步任务又做了进一步的划分,分为了两类,

  1. 宏任务(macrotask)
    • 异步Ajax请求
    • setTimeOut、setInterval
    • 文件操作
    • 其他宏任务
  2. 微任务(microtask)
    • Promise.then、.catch、和.finally
    • process.nextTick
    • 其他微任务
54.png

4.1 宏任务和微任务的执行顺序

55.png
  • 每个宏任务执行完后,都会检查是否存在待执行的微任务
  • 如果有,则会将所有待执行的微任务执行完,再执行下一个宏任务
  • 宏任务和微任务是交替执行的

4.2 根据宏任务和微任务分析代码输出的顺序

setTimeout(()=>{
  console.log(1);
})

new Promise(function(resolve){
  console.log(2);
  resolve()
}).then(res=>{
  console.log(3);
})

console.log(4);

最后的结果是 2 4 3 1

  • setTimeout是一个宏任务,
  • new Promise()是一个同步任务,.then()是一个微任务
  • console.log(4)是一个同步任务

所以执行的顺序是:执行的准则是 先执行同步任务,再去任务队列中读取回调函数放入执行栈中,按次序执行。但异步任务中:先执行微任务,再执行宏任务

  1. new Promise()操作
  2. console.log(4)
  3. .then()
  4. setTimeout

4.3 经典面试题

56.png

先来分析同步任务和异步任务,最后来分析异步任务中的宏任务和微任务

  • 第1行是同步任务1
  • 第3-10行是异步任务1(宏任务)
  • 第12-15行是同步任务2,也就是new Promise()这一部分
  • 第15-17行是异步任务2(微任务)
  • 第20-28行是异步任务3(宏任务)

所以执行顺序是:同步任务js本身自身处理,而异步任务交给宿主环境执行

js本身处理的过程:

  • 执行同步任务1 :输出1
  • 执行同步任务2:输出 5
  • 同步任务执行完
  • 从任务队列中取出执行完对应的回调函数,放入执行栈中,依次执行

宿主环境处理的过程

  • 先执行异步任务2,执行异步任务2,并返回到任务队列中,待主线程执行 输出 6
  • 看是否存在待执行的微任务,发现没有,按次序执行宏任务
  • 先执行 异步任务1 ,并返回到任务队列中,待主线程执行输出 2 3 4
  • 在执行异步任务3 并返回到任务队列中,待主线程执行输出 7 8 9

所以总的输出结果是: 1 5 6 2 3 4 7 8 9

5.总结

EventLoop和宏任务和微任务.png

相关文章

  • js EventLoop、宏任务和微任务

    1.javascript是单线程的语言 javascript是一门单线程执行的编程语言。也就是说,同一时间只能做一...

  • 宏任务和微任务

    [js 宏任务和微任务] .宏任务(macrotask )和微任务(microtask ) macrotask 和...

  • EventLoop和任务队列(微任务和宏任务)

    Eventloop 要说Eventloop,就不得不提浏览器进程和JavaScript单线程的三两事。 浏览器的工...

  • 前端作业

    一、js异步编程的理解,EventLoop、消息队列是做什么的?什么是宏任务、微任务。js是单线程执行,效率低,异...

  • eventLoop 宏任务与微任务

    最近一直准备面试,所以在过架构相关的基础知识(会涉及较多底层),会把很多基础知识都写出来,不过没办法什么都写,主要...

  • 浏览器的事件机制-Eventloop

    循环机制前,我们先要会区分:宏任务与微任务 宏任务Task与微任务Microtask JS中的宏任务和微任务的区别...

  • js中的异步任务:宏任务、微任务

    js的异步任务分2类:宏任务(macrotask )和微任务(microtask ) 什么是宏任务、微任务 网上用...

  • js 宏任务和微任务

    1:主线程 2:.宏任务(macrotask )和微任务(microtask ) 最后看个例子: 分析 • 首先浏...

  • js 宏任务和微任务

    js 执行时首先会从宏任务中获取第一个并执行,执行过程中会将遇到的微任务放入微任务队列,当宏任务执行完成时再去依次...

  • js 宏任务和微任务

    .宏任务(macrotask )和微任务(microtask )macrotask 和 microtask 表示异...

网友评论

      本文标题:js EventLoop、宏任务和微任务

      本文链接:https://www.haomeiwen.com/subject/ycirsrtx.html