当前位置:网站首页>JS 同步、异步,宏任务、微任务概述
JS 同步、异步,宏任务、微任务概述
2022-07-25 15:06:00 【深海蓝山】
一、事件循环机制

主线程运行的时候,产生堆(heap)和栈(stack),栈中的代码调用各种外部API,它们在"任务队列"中加入各种事件(click,load,done)。只要栈中的代码执行完毕,主线程就会去读取"任务队列",依次执行那些事件所对应的回调函数。
主线程运行时会产生执行栈, 栈中的代码调用某些api时,它们会在事件队列中添加各种事件
而栈中的代码执行完毕,就会读取事件队列中的事件,去执行那些回调
如此循环
注意,总是要等待栈中的代码执行完毕后才会去读取事件队列中的事件
二、同步任务、异步任务
JS是单线程的,单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。为了解决排除等待问题,JS的任务分为同步任务(synchronous)和异步任务(asynchronous)。
所有同步任务都在主线程上执行,形成一个执行栈。异步任务不进入主线程,而是进入另一个【任务队列】。同步任务顺序执行,只有执行栈中的同步任务执行完了,系统才回读取任务队列中可以执行的异步任务,才会把此异步任务从事件队列中放入执行栈中执行,如此循环,直至所有任务执行完毕。

- 同步代码直接执行
- 异步函数到了指定时间再放到异步队列
- 同步执行完毕,异步队列轮询执行。
三、宏任务、微任务
macrotask(宏任务),可以理解是每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)
每一个task会从头到尾将这个任务执行完毕,不会执行其它
浏览器为了能够使得JS内部task与DOM任务能够有序的执行,会在一个task执行结束后,在下一个 task 执行开始前,对页面进行重新渲染
宏任务中可以创建微任务,但是在宏任务中创建的微任务不会影响当前宏任务的执行
当一个宏任务队列中的任务全部执行完后,会查看是否有微任务队列,如果有就会优先执行微任务队列中的所有任务,如果没有就查看是否有宏任务队列
常见的宏任务:I/O,setTimeout,setInterval

microtask(微任务),可以理解是在当前 task 执行结束后立即执行的任务
也就是说,在当前task任务后,下一个task之前,在渲染之前
所以它的响应速度相比setTimeout(setTimeout是task)会更快,因为无需等渲染
在上一个宏任务队列执行完毕后,如果有微任务队列就会执行微任务队列中的所有任务
new promise((resolve)=>{ 这里的函数在当前队列直接执行 }).then( 这里的函数放在微任务队列中执行 )
微任务队列上创建的微任务,仍会阻碍后方将要执行的宏任务队列
由微任务创建的宏任务,会被丢在异步宏任务队列中执行
常见的微任务:Promise,process.nextTick
总结:
- 微任务队列优先于宏任务队列执行,
- 微任务队列上创建的宏任务会被后添加到当前宏任务队列的尾端,微任务队列中创建的微任务会被添加到微任务队列的尾端。
- 只要微任务队列中还有任务,宏任务队列就只会等待微任务队列执行完毕后再执行
三、执行顺序
1.主线程上宏任务、微任务执行顺序
console.log('---start---');//第一轮主线程
setTimeout(() => {
console.log('setTimeout'); // 将回调代码放入个宏任务队列,第二轮宏任务执行
}, 0);
new Promise((resolve, reject) => {
console.log('---Promise第一轮微任务同步执行---');//第一轮微任务同步执行
resolve()
}).then(()=>{
console.log('Promise.then实例成功回调执行'); // 将回调代码放入微任务队列,第一轮宏任务执行完后立即执行
});
console.log('---end---');//第一轮主线程结束
执行顺序:主线程 >> 主线程上创建的微任务 >> 主线程上创建的宏任务

2.宏任务中包含微任务
// 宏任务队列 1
setTimeout(() => {
// 宏任务队列 2.1
console.log('timer_1');
setTimeout(() => {
// 宏任务队列 3
console.log('timer_3')
}, 0)
new Promise(resolve => {
resolve()
console.log('new promise')
}).then(() => {
// 微任务队列 1
console.log('promise then')
})
}, 0)
setTimeout(() => {
// 宏任务队列 2.2
console.log('timer_2')
}, 0)
console.log('========== Sync queue ==========')执行顺序:主线程 >> 主线程上的宏任务队列1 >> 宏任务队列1中创建的微任务
========== Sync queue ==========
1 timer_1
2 new promise
3 promise then
4 timer_2
5 timer_3
边栏推荐
- Realsense ROS installation configuration introduction and problem solving
- SPI传输出现数据与时钟不匹配延后问题分析与解决
- "How to use" agent mode
- [C topic] force buckle 876. Intermediate node of linked list
- L1 and L2 regularization
- 37 element mode (inline element, block element, inline block element)
- 深入:微任务与宏任务
- 43 box model
- 06、类神经网络
- MySQL sort
猜你喜欢

树莓派入门:树莓派的初始设置
[Android] recyclerview caching mechanism, is it really difficult to understand? What level of cache is it?

如何解决Visual Stuido2019 30天体验期过后的登陆问题

32 use of chrome debugging tools

Nacos2.1.0 cluster construction

Yarn: the file yarn.ps1 cannot be loaded because running scripts is prohibited on this system.

37 元素模式(行内元素,块元素,行内块元素)

51 single chip microcomputer learning notes (1)

VS2010 add WAP mobile form template

Fast-lio: fast and robust laser inertial odometer based on tightly coupled IEKF
随机推荐
[C topic] Li Kou 206. reverse the linked list
瀑布流布局
【微信小程序】小程序宿主环境详解
sql to linq 之存储过程偏
LeetCode第 303 场周赛
pl/sql 创建并执行oralce存储过程,并返回结果集
(original) customize a scrolling recyclerview
Universal smart JS form verification
冈萨雷斯 数字图像处理 第一章绪论
C#,C/S升级更新
Scala111-map、flatten、flatMap
Bridge NF call ip6tables is an unknown key exception handling
Live classroom system 05 background management system
Award winning interaction | 7.19 database upgrade plan practical Summit: industry leaders gather, why do they come?
43 盒子模型
43 box model
LeetCode-198-打家劫舍
37 元素模式(行内元素,块元素,行内块元素)
SSM Advanced Integration
Sudo rosdep init error ROS installation problem solution