IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 宏任务和微任务 -> 正文阅读

[JavaScript知识库]宏任务和微任务

目录

一、前言

二、宏任务和微任务有哪些?

三、执行顺序

1、事件循环

事件循环的六个阶段

2、题目练习:

练习一

练习二

3、宏任务之间的执行顺序

4、微任务之间的执行顺序

process.nextTick()

5、vue中的nextTick


一、前言

js任务分为同步任务和异步任务,异步任务又分为宏任务和微任务,其中异步任务属于耗时的任务。

二、宏任务和微任务有哪些?

宏任务:整体代码script、setTimeout、setInterval、setImmediate、i/o操作(输入输出,比如读取文件操作、网络请求)、ui render(dom渲染,即更改代码重新渲染dom的过程)、异步ajax等

微任务:Promise(then、catch、finally)、async/await、process.nextTick、Object.observe(?来实时监测js中对象的变化)、 MutationObserver(监听DOM树的变化)

三、执行顺序

js代码在执行的时候,会先执行同步代码,遇到异步宏任务则将异步宏任务放入宏任务队列中,遇到异步微任务则将异步微任务放入微任务队列中,当所有同步代码执行完毕后,再将异步微任务从队列中调入主线程执行,微任务执行完毕后,再将异步宏任务从队列中调入主线程执行,一直循环至所有的任务执行完毕(完成一次事件循环EventLoop)。

注意:

每个异步宏任务执行完之后,都会检查是否存在待执行的微任务;如果有,则执行完所有的微任务之后,再继续执行下一个宏任务。

1、事件循环

一次事件循环只能处理一个宏任务,一次事件循环可以将所有的微任务处理完毕。

事件循环的六个阶段

事件循环是?个循环体,在循环体中有 6 个阶段,在每个阶段中,都有?个事件队列,不同的事件队列存储了不同类型的异步API 的回调函数。 事件循环在每次执?的时候,都有6 个阶段的事情要做:

?

2、题目练习:

练习一

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

分析:
1、遇到setTimeout,异步宏任务将其放到宏任务列表中,命名为time1

2、new Promise 在实例化过程中所执?的代码都是同步执?的( function 中的代码),输出2
3、 Promise 中注册的回调函数放到微任务队列中,命名为 then1
4、 执?同步任务 console.log('4') ,输出 4 ,?此执?栈中的代码执?完毕;
5、 从微任务队列取出任务 then1 到主线程中,输出 3 ,?此微任务队列为空;
6、 从宏任务队列中取出任务 time1 到主线程中,输出 1 ,?此宏任务队列为空

练习二

console.log(1);
setTimeout(function () {
  console.log(2);
  let promise = new Promise(function (resolve, reject) {
    console.log(3);
    resolve();
  }).then(function () {
    console.log(4);
  });
}, 1000);
setTimeout(function () {
  console.log(5);
  let promise = new Promise(function (resolve, reject) {
    console.log(6);
    resolve();
  }).then(function () {
    console.log(7);
  });
}, 0);
let promise = new Promise(function (resolve, reject) {
  console.log(8);
  resolve()
}).then(function () {
  console.log(9);
}).then(function () {
  console.log(10)
});
console.log(11);
//执行顺序:1 8 11 9 10 5 6 7 2 3 4

分析:

1、 执?同步任务 console.log(1) ,输出 1
2、 遇到 setTimeout 放到宏任务队列中,命名 time1
3、 遇到 setTimeout 放到宏任务队列中,命名 time2
?
4、new Promise 在实例化过程中所执?的代码都是同步执?的( function 中的代码),输出8
5、 Promise 中注册的回调函数放到微任务队列中,命名为 then1
6、 Promise 中注册的回调函数放到微任务队列中,命名为 then2
7、 执?同步任务 console.log(11), 输出 11
8、 从微任务队列取出任务 then1 到主线程中,输出 9
9、 从微任务队列取出任务 then2 到主线程中,输出 10 ,?此微任务队列为空;
10、从宏任务队列中取出 time2( 注意这?不是 time1 的原因是 time2 的执?时间为 0);
11、 执?同步任务 console.log(5) ,输出 5
12、new Promise 在实例化过程中所执?的代码都是同步执?的( function 中的代码),输出6
13、 Promise 中注册的回调函数放到微任务队列中,命名为 then3 ,?此宏任务time2执?完成;
14、 从微任务队列取出任务 then3 到主线程中,输出 7 ,?此微任务队列为空;
15、 从宏任务队列中取出 time1 ,?此宏任务队列为空;
16、 执?同步任务 console.log(2) ,输出 2
17、new Promise 在实例化过程中所执?的代码都是同步执?的( function 中的代码),输出3
18、 Promise 中注册的回调函数放到微任务队列中,命名为 then4 ,?此宏任务time1执?完成;
19、 从微任务队列取出任务 then4 到主线程中,输出 4 ,?此微任务队列为空。

3、宏任务之间的执行顺序

宏任务有setTimeout、setInterval、setImmediate、i/o操作、异步的ajax,它们之间的执行也是有先后顺序,它们之间的执行顺序是:
setImmediate -->?setTimeout -->?setInterval -->?i/o操作 -->?异步ajax

例子:

let axios = require('axios');
let fs = require('fs');
console.log('begin');
fs.readFile('1.txt',(err,data)=>{
	console.log('fs');
});
axios.get('https://api.muxiaoguo.cn/api/xiaohua?api_key=fd3270a0a9833e20').then(res=>{
	console.log('axios');
});
setTimeout(()=>{
	console.log('setTimeout')
},0);
setImmediate(()=>{
  console.log('setImmediate');
});
(async function (){
	console.log('async')
})();
console.log('end');
//执行顺序:begin async end setTimeout setImmediate fs axios

setImmediate没有时间参数,它与延迟 0 毫秒的 setTimeout() 回调?常相似。所以当setTimeout延迟时间也是0毫秒时,谁在前面就先执行谁。此外如果setTimeout延迟时间不是0毫秒,它的执行顺序会在 i/o 操作之后。

4、微任务之间的执行顺序

微任务有Promise(then、catch、finally)、process.nextTick等,它们之间执行的先后顺序是:
process.nextTick --> Promise

例子:

console.log('begin');
Promise.resolve().then(()=>{
  console.log('promise');
})
process.nextTick(()=>{
	console.log('nextTick');
});
console.log('end');
//执行顺序:begin end nextTick promise

process.nextTick()

process表示进程,它是一个对象,对象里面有一个nextTick。

nextTick会在上一次事件循环结束,然后在下一次事件循环开始之前执行。

5、vue中的nextTick

Vue.nextTick()?是vue的全局api,它主要用来在下次dom更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的dom。

由于vue的更新机制是异步的,所以当数据修改之后,dom还停留在更新之前,此时想要获取更新后的dom,可以使用nextTick,表示的是下次dom更新循环结束后执行的回调。
应用场景:created 中获取dom可以使用nextTick

<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<script src="https://cdn.jsdelivr.net/npm/vue@2.7.10/dist/vue.js"></script>
</head>

<body>
	<div id="app">
		<ul ref="container">
			<li v-for="(item,index) in arr" :key="index">{{item}}</li>
		</ul>
		<button @click="add">增加</button>
	</div>
	<script>
		new Vue({
			el: "#app",
			data() {
				return {
					arr: ['zhangsan', 'lisi', 'wangwu']
				}
			},
			created() {
				// 使用nextTick可以在created生命周期获取dom节点
				this.$nextTick(() => {
					console.log(this.$refs.container);
				})
			},
			methods: {
				add() {
					this.arr.push(parseInt(Math.random() * 10));
					// 使用nextTick获取数据更新后的dom
					this.$nextTick(() => {
						console.log(this.$refs.container.childNodes);
					});
				}
			}
		})
	</script>
</body>

</html>
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 11:46:33  更:2022-10-31 11:51:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 20:15:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码