feat: js事件循环

master
LCJ-MinYa 3 days ago
parent 0e8a5440ed
commit 38c383eae7

@ -194,6 +194,10 @@ const titleArr = [
key: 'canvasExample', key: 'canvasExample',
title: 'canvas示例', title: 'canvas示例',
}, },
{
key: 'jsEventLoop',
title: 'js事件循环',
},
]; ];
// @/views/demo/**/*.vue // @/views/demo/**/*.vue

@ -0,0 +1,20 @@
<template>
<div
class="markdown-body"
v-html="htmlStr"
/>
</template>
<script setup>
import { ref } from 'vue';
import { marked } from 'marked';
import { getMarkdownContent } from '@/utils/tools';
const htmlStr = ref('');
// getMarkdownContent public
// move-md-plugin src .md public/md/
getMarkdownContent('./md/jsEventLoop.md').then((res) => {
htmlStr.value = marked(res);
});
</script>

@ -0,0 +1,102 @@
# JS 事件循环 (Event Loop)
## 知识点总结(个人整理)
### 执行顺序
1. 同步任务
2. 微任务队列(执行完毕后会再次检查微任务队列,直到清空微任务队列为止)
3. 第一个宏任务
4. 再次检查微任务队列,有就清空
5. 第二个宏任务
...重复上面步骤直到清空宏任务队列
### 代码示例
```javascript
<script>
console.log("同步1");
Promise.resolve().then(() => {
console.log("微任务1");
Promise.resolve().then(() => {
console.log("微任务1-1");
Promise.resolve().then(() => {
console.log("微任务2-1");
});
});
});
setTimeout(() => {
console.log("宏任务1");
Promise.resolve().then(() => {
console.log("宏任务1-微任务");
});
}, 0);
console.log("同步2");
Promise.resolve().then(() => {
console.log("微任务2");
});
setTimeout(() => {
console.log("宏任务2");
}, 0);
console.log("同步3");
</script>
/**
同步1
同步2
同步3
微任务1
微任务2
微任务1-1
微任务2-1
宏任务1
宏任务1-微任务
宏任务2
*/
```
## 知识点总结以下为AI整理
### 1. 为什么会有事件循环?
JavaScript 是单线程的为了协调事件、用户交互、脚本、UI 渲染、网络等,必须使用事件循环。
### 2. 宏任务 (Macrotasks) 与 微任务 (Microtasks)
* **宏任务**: script (整体代码), setTimeout, setInterval, setImmediate (Node.js), I/O, UI rendering.
* **微任务**: Promise.then, process.nextTick (Node.js), MutationObserver.
### 3. 执行顺序
1. 执行一个宏任务(栈为空,执行整体 script 代码)。
2. 执行过程中遇到微任务,将其加入微任务队列。
3. 宏任务执行完毕,立即依次执行当前微任务队列中的所有微任务。
4. 微任务执行完毕,如果有 UI 渲染需求,则进行渲染。
5. 检查是否有宏任务,如果有,取出下一个宏任务,回到第 1 步。
## 代码演示
```javascript
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
Promise.resolve().then(function() {
console.log('promise1');
}).then(function() {
console.log('promise2');
});
console.log('script end');
```
**预期输出顺序:**
1. script start
2. script end
3. promise1
4. promise2
5. setTimeout

@ -134,7 +134,7 @@ const navList = ref<NavItem[]>([
}, },
{ {
title: '事件循环模型', title: '事件循环模型',
path: '/js/event-loop', path: '/demo/jsEventLoop',
desc: '宏任务与微任务的交替执行,浏览器渲染帧的调度机制。', desc: '宏任务与微任务的交替执行,浏览器渲染帧的调度机制。',
}, },
]); ]);

@ -1,12 +1,12 @@
{ {
"totalNotes": 92, "totalNotes": 94,
"categories": 5, "categories": 5,
"lastUpdated": "2026-02-03T02:46:03.140Z", "lastUpdated": "2026-02-06T02:19:56.712Z",
"weeklyAdded": 7, "weeklyAdded": 9,
"categoryChartData": [ "categoryChartData": [
{ {
"name": "demo", "name": "demo",
"value": 81 "value": 83
}, },
{ {
"name": "python", "name": "python",
@ -26,6 +26,18 @@
} }
], ],
"recentNotes": [ "recentNotes": [
{
"path": "demo/jsEventLoop/index.vue",
"title": "js事件循环",
"category": "demo",
"date": "2026-02-06"
},
{
"path": "demo/constructor/index.vue",
"title": "constructor",
"category": "demo",
"date": "2026-02-04"
},
{ {
"path": "demo/canvasExample.vue", "path": "demo/canvasExample.vue",
"title": "canvas示例", "title": "canvas示例",
@ -43,18 +55,6 @@
"title": "面试手写题", "title": "面试手写题",
"category": "demo", "category": "demo",
"date": "2026-02-02" "date": "2026-02-02"
},
{
"path": "demo/formItemWithRangeFields.vue",
"title": "表单一个formItem中校验多个字段",
"category": "demo",
"date": "2026-02-02"
},
{
"path": "demo/formChangeTrack.vue",
"title": "表单敏感字段变更追踪标记",
"category": "demo",
"date": "2026-02-02"
} }
] ]
} }
Loading…
Cancel
Save