【前端面试之JS】微任务和宏任务
什么是微任务和宏任务?
js是一种单线程语言,js中的任务按顺序一个一个的执行,但是如果说一个任务耗时太长的话,后面的任务就要慢慢等待,为了解决这个问题,就将任务分为了同步任务以及异步任务。而异步任务又分为了微任务以及宏任务。
文章目录
- 1、宏任务以及微任务的分类
- 2、执行顺序
- 3、案例
- 案例1
- 案例2
- 案例3
1、宏任务以及微任务的分类
1、宏任务
setTimeoout、setInterval
2、微任务
process.nextTick
这个方法是nodeJS里面的方法,如果说放在html页面中的script标签块中执行,是会报错的。其中process对象是一个全局对象,具有一些可被用来获取nodejs应用程序以及运行该应用程序的用户、运行环境的各种信息的属性、方法和事件。
process.nextTick( callback )方法用于将一个函数推迟到代码中所书写的下一个同步方法执行完毕时或异步方法的事件回调函数开始执行时调用,该方法中使用一个参数,参数值是被推迟的函数。
promise的then方法
就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
2、执行顺序
虽然说都是异步任务,但是执行顺序不同的。
1、存在微任务的话,就执行所有的微任务
2、微任务都执行完之后,执行下一个宏任务
3、但不是说所有宏任务执行完毕之后,才执行微任务的。而是当前的宏任务执行完毕,然后执行所有的微任务(这一点需要注意)
宏任务 | 微任务 | |
---|---|---|
谁发起的 | 宿主(node、浏览器) | JS引擎 |
具体事件 | 1. script (可以理解为外层同步代码)2. setTimeout/setInterval3. UI rendering/UI事件4. postMessage,MessageChannel5. setImmediate,I/O(Node.js) | 1. Promise2. MutaionObserver3. Object.observe(已废弃;Proxy 对象替代)4. process.nextTick(Node.js) |
谁先运行 | 后运行 | 先运行 |
会触发新一轮Tick吗 | 会 | 不会 |
3、案例
案例1
let p = Promise.resolve().then(() => {console.log(p);const timer2 = setTimeout(() => {console.log('timer2')}, 0)
});
const timer1 = setTimeout(() => {console.log('timer1')Promise.resolve().then(() => {console.log('promise2')})
}, 0)
console.log('start');
输出:
代码运行步骤:
1、遇到Promise.resolve().then作为微任务,加入到微任务队列
2、timer1是宏任务,加入到宏任务队列
3、console.log同步代码,输出`start`,主线程中同步任务执行完。
4、微任务队列中有Promise.resolve().then,输出p,因为此时p没有resolve(),以及reject()终止掉,因此会输出`pending`。
4、timer2是宏任务,加入到宏任务队列,此时宏任务队列中有timer1、timer2。
5、微任务执行结束,进入到下一轮宏任务阶段。运行timer1,输出`timer1`,Promise.resolve().then是微任务。
6、宏任务结束,运行微任务,输出`promise2`。
7、微任务运行结束。此时宏任务队列中还有timer2,因此输出`timer2`
案例2
setTimeout(()=>{new Promise(resolve =>{resolve();}).then(()=>{console.log('test');});console.log(4);
});new Promise(resolve => {resolve();console.log(1)
}).then( () => {console.log(3);Promise.resolve().then(() => {console.log('before timeout');}).then(() => {Promise.resolve().then(() => {console.log('also before timeout')})})
})
console.log(2);
输出:
代码运行步骤:
1、遇到setTimeout是宏任务,加入到宏任务队列。
2、new Promise,**在实例化的过程中所执行的代码都是同步进行的**。因此输出`1`。
3、遇到.then,加入到微任务队列
4、console.log同步任务,输出`2`。主线程执行完毕
5、微任务队列中有任务,执行,输出`3`。
6、再次遇到Promise.resolve().then,加入微任务队列,
7、Promise.resolve().then(微任务a).then(微任务b),将其依次放入微任务队列中;
8、从微任务队列中依次取出微任务:输出`before timeout`、`also before timeout`。
9、微任务队列执行完,宏任务队列中还有任务,取出执行。遇到.then,将其放入微任务队列中,遇到同步任务console,输出`4`。宏任务执行完毕。
10、微任务队列中还有数据,因此输出`test`
案例3
若想要异步任务尽可能快的执行,那就使用process.nextTick()
根据语言规格,Promise对象的回调函数,会进入异步任务里面的”微任务“(microtask)队列。微任务队列追加在process.nextTick队列的后面。也属于本轮循环。
请看下面这个例子:
process.nextTick(()=>console.log(1))
Promise.resolve().then(()=>console.log(2))
process.nextTick(()=>console.log(3))
Promise.resolve().then(()=>console.log(4))
输出:1,3,2,4
但是如果换一种方式调用promise结果就不同了
process.nextTick(() => console.log(1))
new Promise(function (resolve) { }).then(console.log(2))
process.nextTick(() => console.log(3))
new Promise(function (resolve) { }).then(console.log(4))
输出是:2,4,1,3
因为new Promise**在实例化的过程中所执行的代码都是同步进行的**,
因此.then先加入到微任务队列中,因此先执行。
【前端面试之JS】微任务和宏任务相关推荐
- 2020年前端面试之JS手写代码题合集
2020年前端面试之JS手写代码题合集 预计会有上千道题,后续慢慢补! 1. 写一个把字符串大小写切换的方法 function caseConvert(str){return str.replace ...
- 2023前端面试(JS专题)
目录 一.前言 二.问题 1,JS数据类型 2,== 与 === 的区别? 3,JS的宏任务和微任务? 4,实现Jsonp 5,JS作用域 6,JS作用域+this指向+原型笔试题(高频) 7, JS ...
- 拯救你的面试:前端面试大全--js面试题(超长文章)
一.什么是编译型语言?什么是解释型语言?JS 是什么类型的语言? 1.编译型语言 1. 解释 程序在执行之前需要一个专门的编译过程,把程序编译成 为机器语言的文件,运行时不需要重新翻译,直接使用编译的 ...
- 前端面试经典js题目Foo 与 getName
面试时遇到了2次该题,结果两次都没有看懂,感觉自己的js功底太差了,跟没学过一样.这道题很经典,网上查了一下,记录一下大佬的思路和自己的理解 题目: function Foo(){getName = ...
- 【前端面试之JS】js如何实现继承
继承(inheritance)是面向对象软件技术当中的一个概念. 如果一个类别B"继承自"另一个类别A,就把这个B称为"A的子类",而把A称为"B的父 ...
- 前端面试系列-JS 异步编程
并发与并行的区别? 并发是宏观概念,我分别有任务 A 和任务 B,在一段时间内通过任务间的切换完成了这两个任务,这种情况就可以称之为并发. 并行是微观概念,假设 CPU 中存在两个核心,那么我就可以同 ...
- 置顶带滚动效果_前端面试:如何实现轮播图效果?
本文将实现如上所示的轮播图.源代码 (https://github.com/z1ming/AKJS/tree/master/%E8%BD%AE%E6%92%AD%E5%9B%BE%E6%95%88%E ...
- 详解队列在前端的应用,深剖JS中的事件循环Eventloop,再了解微任务和宏任务
队列在前端中的应用 一.队列是什么 二.应用场景 三.前端与队列:事件循环与任务队列 1.event loop 2.JS如何执行 3.event loop过程 4. DOM 事件和 event loo ...
- ajax是宏任务还是微任务,(滴滴面试)事件循环Event Loop及微任务和宏任务的执行过程详解...
之前一直在面试,对于一些大厂面试题真的还是很注重原理和基础的, 还有就是数据结构和算法这种,校招的话,这些是很重要的, 前天和滴滴的人面试,问的真心觉得不难,而且也都是现在面试前端很常见的问题, 对于 ...
最新文章
- JVM系列(之ClassLoader)
- python 坐标轴刻度_给妹子讲python-S02E08坐标轴与主次刻度
- 关于tcmalloc\malloc和new
- 使用sql语句创建和删除约束示例代码
- 养心灵,才能美容颜,拥有好日子(图)
- Diango博客--16.稳定易用的 Django 分页库,完善分页功能(二)
- linux中有fd set函数吗,LINUX下FD_SET介绍
- BZOJ2017[USACO 2009 Nov Silver 1.A Coin Game]——DP+博弈论
- Macaca:南方航空人工测试的拯救者
- python装饰器使用
- 【工程项目经验】多个静态库打包成一个静态库
- [转载]Qt之自定义界面(二)添加最小化、关闭按钮、添加背景_vortex_新浪博客...
- python删除文件夹中的jpg_python删除文件夹下相同文件和无法打开的图片
- 数独的优化回朔算法(二)
- PLC编程器的功能有什么功能?
- Struts2面试题大集合
- SpringBoot java串口操作(rxtx)
- MATLAB闪一下打不开问题解决
- [Python]网络爬虫(一):抓取网页的含义和URL基本构成
- c51编译器+linux,C51 开源编译器SDCC学习笔记-安装