- 开始阅读
一、读懂事件循环(Event Loop):
事件循环是javascript运行时的一部分,使得javascript能够处理异步操作,比如事件处理、网络请求和定时器。事件循环的主要作用是监视调用栈和消息队列,如果调用栈为空,那么会将消息队列中的第一个消息移动到调用栈上执行。
- 调用栈(call stack): 用于存储函数调用信息的数据结构。js引擎使用调用栈来管理函数的执行顺序。当一个函数被调用时,会被添加到调用栈的顶端,当函数执行完毕,它会从栈顶移除。
- 消息队列(message queue): 存储了所有待处理的消息,每个消息关联一个回调函数。当调用栈为空的时候,事件循环会从消息队列中取出第一个消息,将其对应的回调函数推到调用栈上执行。
- 事件循环(event loop): 事件循环的工作机制就是不断的检查调用栈是否为空。如果为空,它会从消息队列中取出第一个消息。如果调用栈不为空,则继续等待,直到调用栈为空。
事件循环的工作原理:
- 同步代码: 首先执行同步代码,这些代码会被加入到调用栈中执行。
- 异步代码: 当遇到异步代码(例如setTimeout、promise等),异步代码会被放入消息队列中,等待调用栈执行为
- 事件循环:事件循环不断检查调用栈是否为空,如果为空,则从消息队列中取出一个消息并将其对应的回调函数推到调用栈上执行。
console.log('Start'); // 同步代码,立即执行
setTimeout(() => {
console.log('Timeout'); // 异步代码,在消息队列中等待调用栈为空时执行
}, 0);
Promise.resolve().then(() => {
console.log('Promise'); // 微任务,在当前事件循环的末尾执行
});
console.log('End'); // 同步代码,立即执行
输出结果
Start
End
Promise
Timeout
解析:
- 同步代码执行直接被推到调用栈中执行,因此会立即输出。
- 异步代码为了区分执行顺序,又分为宏任务与微任务。setTimeout是一个宏任务,它将回调函数放入消息队列中,等待调用栈为空时执行。Promise的then方法注册的回调是一个微任务,微任务会在当前时间循环的末尾执行(即在当前同步代码执行完毕之后,下一次时间循环之前)。
- 同步代码执行完毕后,调用栈为空,事件循环检查微任务队列,并立即执行所有微任务。因此,promise的回调优先于setTimeout的回调执行。
- 常见的宏任务: setTimeout、setInterval、I/O操作
- 常见的微任务: promise的then方法、nodejs的process.nextTick(),H5新特性MutationObserver()
总结: javascript 的事件循环是处理异步操作的核心机制。通过调用栈、消息队列、微任务队列和宏任务队列协调同步和异步代码的执行顺序,从而实现非阻塞的并发编程模型。理解事件循环的工作原理对于编写高效、响应迅速的javascript代码至关重要。
- 已完成第一个知识收集