我的编程空间,编程开发者的网络收藏夹
学习永远不晚

浅谈js中的宏任务和微任务

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

浅谈js中的宏任务和微任务

下面一道关于宏任务和微任务的题:


setTimeout(function(){
  console.log('1')
});
 
new Promise(function(resolve){
  console.log('2');
     resolve();
}).then(function(){
 console.log('3')
});
 
console.log('4')

试问一下上面代码的执行顺序是啥?

有小伙伴可能会答:2,4,1,3

估摸着是这么想的:我难道不知道js是一行一行执行的,setTimeout是异步,所以先放后面;往下走,执行了console.log(2) ,.then()是异步的,放在后面;走了console.log(4);再去异步队列里走,先是console.log(1);再是console.log(3)

我有点慌,于是我粘贴到浏览器去瞅两眼:

无法相信

带着困惑的我,只能去好好研究研究JavaScript的运行机制了!

1、关于JavaScript

JavaScript是一门单线程语言,即一次只能完成一个任务,若有多个任务要执行,则必须排队按照队列来执行(前一个任务完成,再执行下一个任务)。

2、JavaScript事件循环

既然js是单线程,那就像只有一个窗口的食堂,学生需要排队一个一个打饭,同理js任务也要一个一个顺序执行。这种模式执行简单,但随着日后的需求,事务,请求增多,这种单线程模式执行效率必定低下。只要有一个任务执行消耗了很长时间,在这个时间里后面的任务无法执行。

常见的有新闻包含的超清图片加载很慢,难道我们的网页要一直卡着直到图片完全显示出来?为了解决这个问题,JavaScript语言将任务执行模式分成同步和异步:

  • 同步模式: 就是上面所说的一种执行模式,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的。
  • 异步模式: 就是每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。

导图要表达的内容用文字来表述的话:

  • 同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。
  • 当指定的事情完成时,Event Table会将这个函数移入Event Queue
  • 主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
  • 上述过程会不断重复,也就是常说的Event Loop(事件循环)。

 再配上代码表达:


let data = [];
$.ajax({
    url:blog.csdn.net,
    data:data,
    success:() => {
        console.log('发送成功!');
    }
})
console.log('代码执行结束');


上面是一段简易的ajax请求代码:

  • ajax进入Event Table,注册回调函数success
  • 执行console.log('代码执行结束')。
  • ajax事件完成,回调函数success进入Event Queue
  • 主线程从Event Queue读取回调函数success并执行。

相信通过上面的文字和代码,你已经对js的执行顺序有了初步了解。然而这也是为什么会有小伙伴回答2,4,1,3的原因。

然而实际上,异步队列里是还有门道的,我们那道面试题,setTimeoutpromise.then()都在异步队列了!接下来,讲讲那些门道(宏任务和微任务)。

3、宏任务和微任务

每个人的理解方式不同,因为宏任务和微任务并不是标准,但执行的顺序在js中是大一统了的。

宏任务:

# 浏览器 Node
<script>整体代码
setTimeout
setInterval
setImmediate x
requestAnimationFrame x
Ajax
DOM事件

微任务:

# 浏览器 Node
process.nextTick x
MutationObserver x
Promise.then catch finally

宏任务包括:<script>整体代码、setTimeoutsetIntervalsetImmediateAjax、DOM事件
微任务process.nextTickMutationObserverPromise.then catch finally

process.nextTick差异太大,不同的node执行不统一,不做标准
微任务比宏任务的执行时间要早

Tip:有些人喜欢将<script>整体代码放在宏任务里,但我个人不喜欢,在我这里它只是第一执行的主线程,我个人是将宏任务和微任务都归类到异步任务里!

我们再来看看那道面试题:


//回调才是异步任务
setTimeout(function(){//宏任务
  console.log('1')
});
 
new Promise(function(resolve){
  console.log('2');//同步主线程
     resolve();
}).then(function(){//微任务
 console.log('3')
});
 
console.log('4')//同步主线程


2:同步中的第一个,故第一

4:同步中的第二个,故第二

3:异步中的微任务,故第三

1:异步中的宏任务,故第二

因此:2,4,3,1的结果就出来了!

除此我们来拓展一下:


setTimeout(() => {//宏任务队列1
  console.log('1');//宏任务队1的任务1

  setTimeout(() => {//宏任务队列3(宏任务队列1中的宏任务)
    console.log('2')
  }, 0)

  new Promise(resolve => {
    resolve()
    console.log('3')//宏任务队列1的任务2
  }).then(() => {//宏任务队列1中的微任务
    console.log('4')
  })

}, 0)
 
setTimeout(() => {//宏任务队列2
  console.log('5')
}, 0)

console.log('6')//同步主线程

执行整体代码(宏任务)console.log('6') >> 宏任务队列1、宏任务队列2位异步(依次执行)

宏任务队列1:=>

        console.log('1')

        console.log('3')

        console.log('4')//宏任务中的微任务

        剩下的不会先执行,因为是宏任务中的宏任务(console.log(2)) ,要被继续丢进任务队列后  

宏任务队列2:=>

         console.log('5')

宏任务队列1中的宏任务3:=>

        console.log('2')

 以上代码会怎么输出呢?

4、拓展宏任务微任务

上面出了复杂的题,小伙伴们不妨可以想一想,这种复杂情况,一个套一个的该怎么执行呢?

  • 6:第一个同步主线程,故第一

script整体代码里没有微任务故直接执行宏任务=>

宏任务队列:

 宏任务队列1

  • 任务1:console.log(1)
  • 任务2:console.log(3)
  • 宏任务队列1中的微任务:console.log(4)
  • 宏任务队列3:因他是宏任务队列1中的宏任务,所以被丢进了任务队列最后,我们先看宏任务队列1同级的是否还有宏任务,有就先执行同级的,没有才可以执行宏任务队列3!故最后!

宏任务队列2  

console.log(5)

所以输出的结果是什么?是6,1,3,4,5,2!

经过验证,结果正确!

到此这篇关于浅谈js中的宏任务和微任务的文章就介绍到这了,更多相关js中的宏任务和微任务内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

浅谈js中的宏任务和微任务

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

JS的执行机制(EventLoop、宏任务和微任务)

这篇文章主要介绍了JS的执行机制(EventLoop、宏任务和微任务),具有很好的参考价值,希望对大家有所帮助。
2023-01-28

JavaScript中宏任务和微任务有哪些

小编给大家分享一下JavaScript中宏任务和微任务有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1、微任务有哪些Promiseawait和async2、
2023-06-25

JavaScript中的宏任务和微任务执行顺序

在 JavaScript 中,宏任务和微任务是指在执行代码的过程中的两种不同的任务类型,这篇文章主要介绍了JavaScript中的宏任务和微任务执行顺序,需要的朋友可以参考下
2022-12-27

深入理解JavaScript中的宏任务和微任务机制

JavaScript中的任务分为宏任务和微任务,它们的执行顺序会影响代码的执行结果。了解它们的机制可以帮助我们更好地理解事件循环和异步编程,避免出现一些意想不到的错误
2023-05-18

vue中的任务队列和异步更新策略(任务队列,微任务,宏任务)

这篇文章主要介绍了vue中的任务队列和异步更新策略(任务队列,微任务,宏任务),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2022-11-13

如何进行JavaScript微任务和宏任务的分析

这篇文章将为大家详细讲解有关如何进行JavaScript微任务和宏任务的分析,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。前言:js是一门单线程语言,所以它本身是不可能异步的,但是js的宿主
2023-06-22

JavaScript中的宏任务和微任务执行顺序是什么

这篇“JavaScript中的宏任务和微任务执行顺序是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“JavaScript
2023-07-04

深入理解JS中的微任务和宏任务的执行顺序及应用场景

JavaScript中的任务分为宏任务和微任务,它们的执行顺序会影响代码的执行结果。了解它们的机制可以帮助我们更好地理解事件循环和异步编程,避免出现一些意想不到的错误
2023-05-19

浅析Shell中的定时任务 crontab

crondtab定时任务 crondtab是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,crondtab进程每分钟会定期检查是否有要执行的任务,如果有要执行的任务,则自动执行www
2022-06-04

编程热搜

目录