知识扩展学习
异步编程是一种通用的编程范式,很多语言都有实现(异步是编程思想:Java、Python、Go 都有异步),但 JavaScript 因为是单线程语言,对异步编程依赖度最高,通过「JS 引擎 + 宿主环境」共同实现事件循环、宏任务 / 微任务机制。
异步编程 ≠ JavaScript,JS 是单线程语言,为了避免耗时操作阻塞主线程导致页面卡顿,所以强制依赖异步编程模型...
1.异步编程与JS的关系?
1.不等同 :异步是一种通用的编程范式,并非 JS 独有。
2.核心依赖 :JS 是单线程语言,同一时间只能做一件事。
3.必要性:为了防止耗时的 I/O 操作(网络请求、文件读写)阻塞主线程导致页面卡死,JS 必须依赖异步编程,通过非阻塞方式处理并发任务。
2.JS 中的异步编程是如何执行的?
JS 的执行遵循 事件循环(Event Loop) 机制 ,具体流程【文档理解】:
1.执行同步代码 :优先执行调用栈中的同步任务。
2.处理微任务 (Microtasks):同步任务执行完毕后,立即将微任务队列(Promise、queueMicrotask 等)中的所有任务清空。
3.更新渲染 :浏览器进行页面渲染(UI 线程)。
4.处理宏任务(Macrotasks) :从宏任务队列(setTimeout、AJAX、事件等)中取出一个任务执行。
5.循环往复 :重复上述步骤。
一句话总结:同步执行完 -> 清空微任务(这里用'清空',是因为需要一次性全部执行完!) -> 执行一个宏任务 -> 再清空微任务...... 如此循环。
【个人理解】:
在同一个事件循环内:先执行同步任务,等所有同步任务执行完毕后,再执行异步任务(注:异步任务也分执行顺序:微任务先执行 promise,宏任务后执行 - 浏览器的定时器任务等)
3.所谓事件循环,应该说的就是在一个事件内?
【答:是的】,
事件循环 = 一次循环 = 一个 "事件周期 / 一轮循环"
JS 执行的【一轮完整循环】这一轮里固定做三件事,做完算一轮,然后开始下一轮:
1.执行同步代码
2.执行所有微任务
3.执行一个宏任务
这三件事走完 → 这一轮事件循环结束
实践案例:
css
console.log('1 同步');
setTimeout(() => {
console.log('2 宏任务1');
Promise.resolve().then(() => {
console.log('3 宏任务1里的微任务');
});
}, 0);
Promise.resolve().then(() => {
console.log('4 微任务1');
});
Promise.resolve().then(() => {
console.log('5 微任务2');
});
setTimeout(() => {
console.log('6 宏任务2');
}, 0);
console.log('7 同步');
最后运行结果:
1 同步
7 同步
4 微任务1
5 微任务2
2 宏任务1
3 宏任务1里的微任务
6 宏任务2
再次总结:
同一个事件循环内:
执行所有同步任务
执行所有微任务(清空)
执行一个宏任务
执行完这个宏任务后,立刻检查并清空所有微任务
4.事件循环和事件委托的关系?
【答:完全没关系】
1.事件循环:JS 代码执行顺序机制(异步、同步、微任务、宏任务)
2.事件委托:DOM 事件绑定优化方案(例如:利用事件冒泡,把事件绑在父元素上,用来管理子元素的点击等行为。)
5.JS中常使用的几种异步编程方式 ?
1.Callback(回调函数,需要避免回调地狱...)
2.Promise: pending(等待中)、fulfilled(成功)、rejected(失败)状态一旦改变就不可逆!
3.async/await 优点:代码同步写法、可读性强、错误处理方便、缺点:不能并行执行(需配合 Promise.all)
6.宏任务(Macrotask)
答:宏任务:排队一个一个执行、微任务:一次性全部执行完
1.概念 :
由 浏览器 / Node 环境提供 的异步任务。特点:一次事件循环只执行一个!
2.包含哪些?
script 标签里的整体代码
setTimeout / setInterval(定时器)
AJAX/fetch(网络请求)
DOM 事件(click、scroll、load)
I/O 操作(文件读写)
3.执行规则
排队执行、一次只执行一个
执行完一个,必须去检查微任务
7.微任务(Microtask)
1. 概念:
由 JS 引擎自身提供 的异步任务。特点:必须一次性全部清空,才允许继续!
2. 包含哪些?
Promise.then / catch / finally(最重要)
queueMicrotask()
MutationObserver(监听 DOM 变化)
process.nextTick(Node 里)
3. 执行规则
队列里所有微任务一次性执行完
执行不完绝不往下走
执行完才允许执行下一个宏任务
8.微任务和宏任务区别?
微任务(优先执行):Promise.then/catch/finally(async/await 是其语法糖)、process.nextTick(Node)、queueMicrotask、MutationObserver(浏览器)
宏任务(后执行) :浏览器:setTimeout、setInterval、fetch/AJAX、DOM 事件、requestAnimationFrame
Node:setTimeout、setInterval、fs.readFile、I/O 操作网络请求
执行顺序:在一个事件循环内,
1.执行所有同步 →
2.执行所有微任务 →
3.执行1个宏任务,
4.执行完宏任务后,再次回到步骤 2,清空所有新产生的微任务
5.循环往复...