理解JS事件循环

时间:2021-05-18

伴随着JavaScript这种web浏览器脚本语言的普及,对它的事件驱动交互模型,以及它与Ruby、Python和Java中常见的请求-响应模型的区别有一个基本了解,对您是有益的。在这篇文章中,我将解释一些JavaScript并发模型的核心概念,包括其事件循环和消息队列,希望能够提升你对一种语言的理解,这种语言你可能已经在使用但也许并不完全理解。

这篇文章是写给谁的?

这篇文章是针对在客户端或服务器端使用或计划使用JavaScript的web开发人员的。如果你已经精通事件循环,那么这篇文章的大部分对你来说会很熟悉。对于那些还不是很精通的人,我希望能给你提供一个基本的了解,这样可以更好地帮助你阅读和编写日常代码。

非阻塞I / O

在JavaScript中,几乎所有的I/O都是非阻塞的。这包括HTTP请求,数据库操作和磁盘读写,单线程执行要求在运行期执行一个操作时,提供一个回调函数,然后继续做其它的事情。当操作已经完成时,消息和已提供的回调函数一起插入到队列。在将来的某个时候,消息从队列移除,回调函数触发。

虽然这种交互模型可能对已经习惯使用用户界面的开发人员很熟悉,比如“mousedown,”和“click”事件在某一时刻被触发。这与通常在服务器端应用程序进行的同步式请求-响应模型是不同的。

让我们来比较一下两小块代码,发出HTTP请求到putePiToSpecifiedDecimals(e.data); postMessage(pi);}; onmessage = reportResult;

然后,主要的代码块在我们的HTML中以script-标签存在:

// our main code, in a <script>-tag in our HTML pagevar piWorker = new Worker("pi_calculator.js");var logResult = function(e) { console.log("PI: " + e.data);}; piWorker.addEventListener("message", logResult, false);piWorker.postMessage(100000);

在这个例子中,主线程创建一个worker,同时注册logResult回调函数到其“消息”事件。在worker里,reportResult函数注册到自己的“消息”事件中。当worker线程接收到主线程的消息,worker入队一条消息同时带上reportResult回调函数。消息出队时,一条新消息发送回主线程,新消息入队主线程队列(带上logResult回调函数)。这样,开发人员可以将cpu密集型操作委托给一个单独的线程,使主线程解放出来继续处理消息和事件。

关于闭包的

JavaScript对闭包的支持,允许你这样注册回调函数,当回调函数执行时,保持了对他们被创建的环境的访问(即使回调的执行时创建了一个全新的调用栈)。理解我们的回调作为一个不同的消息的一部分被执行,而不是创建它的那个会很有意思。看看下面的例子:

function changeHeaderDeferred() { var header = document.getElementById("header"); setTimeout(function changeHeader() { header.style.color = "red"; return false; }, 100); return false;} changeHeaderDeferred();

在这个例子中,changeHeaderDeferred函数被执行时包含了变量header。函数 setTimeout被调用,导致消息(带上changeHeader回调)被添加到消息队列,在大约100毫秒后执行。然后 changeHeaderDeferred函数返回false,结束第一个消息的处理,但header变量仍然可以通过闭包被引用,而不是被垃圾回收。当 第二个消息被处理(changeHeader函数),它保持了对在外部函数作用域中声明的header变量的访问。一旦第二个消息 (changeHeader函数)执行结束,header变量可以被垃圾回收。

提醒

JavaScript 事件驱动的交互模型不同于许多程序员习惯的请求-响应模型,但如你所见,它并不复杂。使用简单的消息队列和事件循环,JavaScript使得开发人员在构建他们的系统时使用大量asynchronously-fired(异步-触发)回调函数,让运行时环境能在等待外部事件触发的同时处理并发操作。然而,这不过是并发的一种方法。

以上就是本文的全部内容,希望对大家的学习有所帮助。

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章