JS的宏任务和微任务是什么,队列是怎样的
Admin 2022-09-13 群英技术资讯 486 次浏览
首先我们要了解javascript是一个单线程的脚本语言,也就是说我们在执行代码的过程中不会出现同时进行两个进程(执行两段代码)。
Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。
同步:一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去。
异步:进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。
进程:狭义上,就是正在运行的程序的实例。广义上,进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。描述的是CPU在运行指令及加载和保存上下文所需要的时间。
线程:是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位。指运行中的程序的调度单位。
执行栈:V8(谷歌浏览器引擎)内部维护出来的一个用来存放函数的执行上下文环境的一个栈结构。
相信有不少人和我有着一样的疑惑,既然javascript是单线程的脚本语言,那么他有什么优势呢,为什么不写成多进程的呢?
(macro)task,可以理解是每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)。
requestAnimationFrame在MDN的定义为,下次页面重绘前所执行的操作,而重绘也是作为宏任务的一个步骤来存在的,且该步骤晚于微任务的执行。
microtask,可以理解是在当前 task 执行结束后立即执行的任务。也就是说,在当前task任务后,下一个task之前,在渲染之前。
所以它的响应速度相比setTimeout(setTimeout是task)会更快,因为无需等渲染。也就是说,在某一个macrotask执行完后,就会将在它执行期间产生的所有microtask都执行完毕(在渲染前)。
上面我们讲了半天宏任务、微任务等各种任务的执行那么vent-Loop到底是个啥?
javascript是一个单进程的语言,同一时间不能处理多个任务,所以什么时候执行宏任务什么时候执行微任务呢?于是乎我们需要Event Loop-事件循环机制(计算机系统的一种运作机制)这样一个判断逻辑存在。
同步代码: js为脚本语言,对于同步代码来说,自上而下进行解释执行。
异步代码: 对于一个任务,分为多个片段来进行执行, 先执行一段,如果碰到比较耗时间的操作,比如本地或者网络io请求。 第一段开始进行io之后,把执行权交由其他任务,当io完成后再来执行后半段的任务(io操作比较耗时,在系统进行io时,主线程是空闲的)
1. 首先执行同步代码,这属于宏任务;
2. 当执行完所有的同步代码后,执行栈为空,检查是否有异步代码要执行;
3. 执行微任务;
4. 执行完微任务后,有必要的情况下会渲染页面;
5. 开启下一轮 Event Loop,执行宏任务中的代码;
代码在执行过程中,遇到异步代码,会将异步代码用队列装起来(挂起)
实战出真理,我们用一个感受一下
console.log('start'); // 1
function foo(){
console.log('foo');
}
foo() // 2
setTimeout(function() { //异步代码中的宏任务,先挂起
console.log('setTimeout'); // 7
},1000)
new Promise(resolve =>{
console.log('promise'); // 3
resolve()
})
.then(function() { //异步代码中的微任务,先挂起
console.log('promise1');// 5
})
.then(function() { //异步代码中的微任务,先挂起
console.log('promise2');// 6
})
console.log('end'); // 4
我们跟着实行顺序来分析,第一步首先执行同步代码,所以首先打印出来‘start’,调用函数foo打印出来‘foo’,执行Promise函数打印出来‘promise’,最后打印出来‘end’同步代码就执行完毕,再检查是否有异步代码要执行,第三步执行微任务,所以先打印出第一微任务列表中的‘promise1’,紧接着打印第二微任务列表中的‘promise2’纯js不用渲染页面,最后开启下一轮的Event-Loop,执行宏任务中的代码,而setTimeout就是异步代码中的宏任务所以最终打印出来‘setTimeout’,最后我们来看看在谷歌浏览器中的打印效果。
这里有个小细节,如果将定时器setTimeout的时间设置为0呢?结果其实还是一样的,setTimeout不会因为时间而改变执行顺序,因为它仍然是异步代码中的宏任务,不会因为延迟执行的时间而改变。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
创建简单对象:使用对象字面量{}创建对象。用function(函数)模拟class(无参构造函数)。使用工厂创建(Object关键字)。prototype关键字采用原型对象。混合模式(原型和构造函数)。
怎样用vue实现点赞动画效果?现在很多网站平台都有点赞功能,这篇文章就给大家分享怎样用vue实现一个好看的点赞动画,当点赞时,同时点亮爱心和增加点赞数,效果如下,感兴趣的朋友就继续往下看吧。
在前面随笔《循序渐进VUE+Element 前端应用开发之动态菜单和路由的关联处理》中介绍了在Vue + Element整合框架中,实现了动态菜单和动态路由的处理,从而可以根据用户角色对应的菜单实现本地路由的过滤和绑定,菜单顺利弄好了,就需要进一步开发页面功能了,本篇随笔介绍一个案例,通过获取后端数据后,进行产品信息页面的处理。
怎样使用js实现碰撞检测?碰撞效果在很多游戏中都会使用到,下面给大家分享一个js实现碰撞的简单测试。当小物体碰撞大物体,大物体颜色改变,效果如下。
问题:canvas绘制图片,图片变模糊设定一个一定尺寸的canvas,我这里设置的画布大小是400px*400px。当一张图片完全画到画布上的时候,大概率都会出现图片模糊的情况。我拿下面一张图片画到canvas上作为例子,看上去应该比较明显的有模糊的感觉。单方面的去修改图片精度,换成更高清的图片,事实证明确实有一丢丢用
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008