事件循环_经典面试题
目录
代码分析
代码解读
执行顺序
执行结果
结论
文件名:
在JavaScript中,理解事件循环(Event Loop)是掌握异步编程的基础。事件循环决定了代码的执行顺序,包括宏任务(Macrotasks)和微任务(Microtasks)的调度。为了更好地理解事件循环,我们通过一个经典的面试题来展示JavaScript中的异步执行顺序。
代码分析
这是一个简单的HTML文件,包含了一段JavaScript代码,我们可以通过这段代码来分析JavaScript事件循环的执行顺序。
<!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>事件循环经典_经典面试题</title>
</head>
<body>
<script>
// 目标:回答代码执行顺序
console.log(1)
setTimeout(() => {
console.log(2)
const p = new Promise(resolve => resolve(3))
p.then(result => console.log(result))
}, 0)
const p = new Promise(resolve => {
setTimeout(() => {
console.log(4)
}, 0)
resolve(5)
})
p.then(result => console.log(result))
const p2 = new Promise(resolve => resolve(6))
p2.then(result => console.log(result))
console.log(7)
</script>
</body>
</html>
代码解读
-
第一行
console.log(1)
:- 这行代码会被立即执行,输出
1
。
- 这行代码会被立即执行,输出
-
第二部分
setTimeout(() => {...}, 0)
:setTimeout
是一个宏任务(Macrotask),它会被放入任务队列,等待所有同步代码执行完毕后执行。这里设定了0毫秒的延迟,因此它会尽快执行,但仍然会排在所有同步任务之后。
-
第三部分
const p = new Promise(resolve => {...})
:- 创建了一个Promise对象,并且立即执行resolve操作,
resolve(5)
会将结果5传递给then
方法。因此,它会进入微任务队列。
- 创建了一个Promise对象,并且立即执行resolve操作,
-
第四部分
const p2 = new Promise(resolve => resolve(6))
:- 这部分是另一个Promise对象,它会在同步代码执行完毕后立即执行
then
方法,输出6。由于它是同步Promise,它会立即进入微任务队列。
- 这部分是另一个Promise对象,它会在同步代码执行完毕后立即执行
-
第五行
console.log(7)
:- 这行代码是同步代码,会直接执行,输出
7
。
- 这行代码是同步代码,会直接执行,输出
执行顺序
JavaScript的事件循环机制是单线程的,并且执行顺序是严格按照宏任务和微任务的优先级顺序来的。执行顺序如下:
-
同步任务 按顺序执行:
- 输出
1
(来自console.log(1)
)。 - 输出
7
(来自console.log(7)
)。
- 输出
-
微任务 在当前同步任务执行完毕后,立即执行:
- 输出
6
(来自p2.then(...)
)。 - 输出
5
(来自p.then(...)
)。
- 输出
-
宏任务 执行(微任务执行完后再执行宏任务):
- 输出
2
(来自setTimeout
中的回调)。 - 输出
3
(来自p.then(...)
内的Promise
回调)。 - 输出
4
(来自另一个setTimeout
内的回调)。
- 输出
执行结果
1
7
6
5
2
3
4
结论
通过上面的代码执行顺序可以得出,JavaScript事件循环遵循如下的执行优先级:
- 同步任务:立即执行。
- 微任务:当前同步任务执行完毕后,执行所有微任务。
- 宏任务:所有微任务执行完毕后,再开始执行宏任务。
这个例子是一个典型的事件循环模型,展示了宏任务和微任务的执行顺序,帮助我们理解 JavaScript 中的异步执行机制。
文件名:
index.html