0

0

理解JS事件循环_javascript技巧

php中文网

php中文网

发布时间:2016-05-16 15:21:26

|

1946人浏览过

|

来源于php中文网

原创

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

这篇文章是写给谁的?

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

非阻塞I / O

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

立即学习Java免费学习笔记(深入)”;

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

让我们来比较一下两小块代码,发出HTTP请求到www.google.com和输出响应到控制台。首先看看Ruby,配合使用Faraday(一个Ruby 的HTTP 客户端开发库):

response = Faraday.get 'http://www.google.com'
puts response
puts 'Done!'

执行路径很容易跟踪:

1、执行get方法,执行的线程等待,直到收到响应
2、从谷歌收到响应并返回给调用者,它存储在一个变量中
3、变量的值(在本例中,就是我们的响应)输出到控制台
4、值“Done!“输出到控制台
让我们使用Node.js和Request库在JavaScript做同样的事情:

request('http://www.google.com', function(error, response, body) {
 console.log(body);
});
 
console.log('Done!');

表面上看略有不同,实际行为截然不同:

1、执行请求函数,传递一个匿名函数作为回调,当响应在将来某个时候可用时执行回调。
2、“Done!“立即输出到控制台
3、在将来的某个时候,响应返回和回调执行时,输出它的内容到控制台
事件循环

将调用者和响应解耦,使得JavaScript在运行期等待异步操作完成和回调触发时可以做其他事情。但是这些回调在内存中是如何组织的,按什么顺序执行?什么导致他们被调用?

JavaScript运行时包含一个消息队列,它存储了需要处理的消息的列表和相关的回调函数。这些消息是以队列的形式来响应回调函数所涉及的外部事件(如鼠标单击或收到HTTP请求的响应)的。例如,如果用户单击一个按钮,但没有提供回调函数,那么也没有消息会被加入队列。

在一次循环,队列提取下一条消息(每次提取称为一次“tick”),当事件发生,该消息的回调执行。

回调函数的调用在调用栈作为初始化frame(片段),由于JavaScript是单线程的,未来的消息提取和处理因为等待栈的所有调用返回而被停止。后续(同步)函数调用会添加新的调用frame到栈(例如,函数init调用函数changeColor)。

function init() {
 var link = document.getElementById("foo");
 
 link.addEventListener("click", function changeColor() {
  this.style.color = "burlywood";
 });
}
 
init();

在这个例子中,当用户单击“foo”元素时,一条消息(及其回调函数changeColor)会被插入到队列,并触发“onclick“事件。当消息离开队列时,其回调函数changeColor被调用。当changeColor返回(或者是抛出一个错误),事件循环仍在继续。只要函数changeColor存在,并指定为“foo”元素的onclick方法的回调,那么在该元素上单击会导致更多的消息(和相关的回调changeColor)插入队列。

队列附加消息

Type
Type

生成草稿,转换文本,获得写作帮助-等等。

下载

如果一个函数在代码中按异步调用(比如setTimeout),提供的回调将最终作为一个不同的消息队列的一部分被执行,它将发生在事件循环的某个未来的动作上。例如:

function f() {
 console.log("foo");
 setTimeout(g, 0);
 console.log("baz");
 h();
}
 
function g() {
 console.log("bar");
}
 
function h() {
 console.log("blix");
}
 
f();

由于setTimeout的非阻塞特性,它的回调将在至少0毫秒后触发,而不是作为消息的一部分被处理。在这个示例中,setTimeout被调用, 传入了一个回调函数g且延时0毫秒后执行。当我们指定时间到达(当前情况是,几乎立即执行),一个单独的消息将被加入队列(g作为回调函数)。控制台打印的结果会是像这样:“foo”,“baz”,“blix”,然后是事件循环的下一个动作:“bar”。如果在同一个调用片段中,两个调用都设置为setTimeout -传递给第二个参数的值也相同-则它们的回调将按照调用顺序插入队列。

Web Workers

使用Web Workers允许您能够将一项费时的操作在一个单独的线程中执行,从而可以释放主线程去做别的事情。worker(工作线程)包括一个独立的消息队列,事件循 环,内存空间独立于实例化它的原始线程。worker和主线程之间的通信通过消息传递,看起来很像我们往常常见的传统事件代码示例。

首先,我们的worker:

// our worker, which does some CPU-intensive operation
var reportResult = function(e) {
 pi = SomeLib.computePiToSpecifiedDecimals(e.data);
 postMessage(pi);
};
 
onmessage = reportResult;

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

// our main code, in a 
                

相关专题

更多
java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

2

2026.01.29

java配置环境变量教程合集
java配置环境变量教程合集

本专题整合了java配置环境变量设置、步骤、安装jdk、避免冲突等等相关内容,阅读专题下面的文章了解更多详细操作。

2

2026.01.29

java成品学习网站推荐大全
java成品学习网站推荐大全

本专题整合了java成品网站、在线成品网站源码、源码入口等等相关内容,阅读专题下面的文章了解更多详细推荐内容。

0

2026.01.29

Java字符串处理使用教程合集
Java字符串处理使用教程合集

本专题整合了Java字符串截取、处理、使用、实战等等教程内容,阅读专题下面的文章了解详细操作教程。

0

2026.01.29

Java空对象相关教程合集
Java空对象相关教程合集

本专题整合了Java空对象相关教程,阅读专题下面的文章了解更多详细内容。

3

2026.01.29

clawdbot ai使用教程 保姆级clawdbot部署安装手册
clawdbot ai使用教程 保姆级clawdbot部署安装手册

Clawdbot是一个“有灵魂”的AI助手,可以帮用户清空收件箱、发送电子邮件、管理日历、办理航班值机等等,并且可以接入用户常用的任何聊天APP,所有的操作均可通过WhatsApp、Telegram等平台完成,用户只需通过对话,就能操控设备自动执行各类任务。

25

2026.01.29

clawdbot龙虾机器人官网入口 clawdbot ai官方网站地址
clawdbot龙虾机器人官网入口 clawdbot ai官方网站地址

clawdbot龙虾机器人官网入口:https://clawd.bot/,clawdbot ai是一个“有灵魂”的AI助手,可以帮用户清空收件箱、发送电子邮件、管理日历、办理航班值机等等,并且可以接入用户常用的任何聊天APP,所有的操作均可通过WhatsApp、Telegram等平台完成,用户只需通过对话,就能操控设备自动执行各类任务。

16

2026.01.29

Golang 网络安全与加密实战
Golang 网络安全与加密实战

本专题系统讲解 Golang 在网络安全与加密技术中的应用,包括对称加密与非对称加密(AES、RSA)、哈希与数字签名、JWT身份认证、SSL/TLS 安全通信、常见网络攻击防范(如SQL注入、XSS、CSRF)及其防护措施。通过实战案例,帮助学习者掌握 如何使用 Go 语言保障网络通信的安全性,保护用户数据与隐私。

8

2026.01.29

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

622

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.3万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.5万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号