js中的宏任务和微任务怎么用

发布时间:2021-09-26 10:09:50 作者:小新
来源:亿速云 阅读:119

这篇文章给大家分享的是有关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)

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

js中的宏任务和微任务怎么用

无法相信

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

1、关于JavaScript

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

2、JavaScript事件循环

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

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

js中的宏任务和微任务怎么用

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

 再配上代码表达:

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

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

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

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

3、宏任务和微任务

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

宏任务:

#浏览器Node
<script>整体代码
setTimeout
setInterval
setImmediatex
requestAnimationFramex
Ajax
DOM事件

微任务:

#浏览器Node
process.nextTickx
MutationObserverx
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、拓展宏任务微任务

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

js中的宏任务和微任务怎么用

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

宏任务队列:

 宏任务队列1

宏任务队列2  

console.log(5)

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

js中的宏任务和微任务怎么用

感谢各位的阅读!关于“js中的宏任务和微任务怎么用”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

推荐阅读:
  1. 任务
  2. JS中宏任务与微任务的原理解析

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

js

上一篇:Linux操作系统的应急技巧有哪些

下一篇:C++中delete之静态变量问题的示例分析

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》