- Objective: - Breadcrumb: # 概念阐释 事件循环可以在JavaScript中运行非代码阻塞,模拟并发性。当运行[[JavaScript 异步编程]]函数时,事件循环管理了代码执行的顺序。 *非代码阻塞、并发、异步编程其实都是一回事,2个以上的线程同时执行。* ![](http://image.harryrou.wiki/2023-08-15-CleanShot%202023-08-15%20at%2011.22.09%402x.png) 2种[[数据结构]]堆和调用栈与节点和[[Web API]]交互,Web API通过事件队列将消息传回堆栈,事件队列与调用堆栈的交互由事件循环管理。 ### [[堆栈#^304f7d|堆]] 无序存储对象的内存块。当前使用的 JavaScript 变量和对象存储在堆中。 ### 调用[[堆栈]] 当[[调用函数]]时,就会像堆栈中添加一个帧,一个帧代表一个要执行的代码,按照LIFO先进后出的顺序进入堆栈,当函数完成时,帧将从堆栈中删除。 ```js function foo() { return function bar() {    return function baz() {      return 'I love CodeCademy'    } } } console.log(foo()()()); ``` #### 添加堆栈 ![](http://image.harryrou.wiki/2023-08-15-CleanShot%202023-08-15%20at%2011.36.30.gif) #### 删除堆栈 ![](http://image.harryrou.wiki/2023-08-15-CleanShot%202023-08-15%20at%2011.37.28.gif) ### 事件队列 等待处理的函数的列表,从各种WebAPI或被调用的异步函数,按照**FIFO先进先出**的顺序等待进入队列。 ### 事件循环 当堆栈为空时,事件队列中的事件将被添加到堆栈,循环这一过程。 ### 节点和WebAPI # 实例 ```js console.log("This is the first line of code in app.js."); function usingsetTimeout() {     console.log("I'm going to be queued in the Event Loop."); } setTimeout(usingsetTimeout, 3000); console.log("This is the last line of code in app.js."); ``` - `console.log("This is the first line of code in app.js."); `添加到堆栈中,执行,弹出; - `setTimeout();`添加到堆栈中; - 执行WebAPI,`setTimeout(usingsetTimeout, 3000); `在3秒钟后被推送到事件队列; - 事件循环定期查询堆栈,为空时加入事件队列消息; - `console.log("This is the last line of code in app.js.");`添加到堆栈中,执行,弹出。 - 最后一行执行完了,`usingsetTimeout()`被压入堆栈 - `console.log("I'm going to be queued in the Event Loop.");`添加到堆栈、执行、弹出 2. `usingsetTimeout`从堆栈中弹出。 # 相关内容 ## 阻塞与非阻塞的区别 ```js //阻塞实例 console.log("I'm learning about"); for (let idx=0; idx < 999999999; idx++) {} // The second console.log() statement is // delayed by the for loop's execution console.log("the Event Loop"); //非阻塞实例,用setTimeout(),会先执行2个console,再执行setTimeout;使用事件循环,不用在等待时停止代码执行 console.log("I’m learning about"); setTimeout(() => { console.log("Event Loop");}, 2000); console.log("the"); ``` - 这个例子中,JavaScript仍然是单线程,但事件循环启用了并发性 # 参考资料 - [Concurrency Model and Event Loop in JavaScript并发模型和事件循环](https://www.codecademy.com/courses/learn-intermediate-javascript/articles/javascript-concurrency-model-and-event-loop) - [并发事件与事件循环](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Event_loop)