在 JavaScript 和 Node.JS 中什么是 "事件驱动"? 下面本篇文章给大家介绍一下. 有一定的参考价值, 有需要的朋友可以参考一下, 希望对大家有所帮助.
事件驱动和发布 - 订阅
事件驱动架构是建立在软件开发中一种通用模式上的, 这种模式被称为发布 - 订阅或观察者模式.
在事件驱动架构中, 至少有两个参与者: 主题 (subject) 和观察者(observer).
主题就像调频收音机一样, 向有兴趣收听该主题所说内容的观察者进行广播.
观察者可能只有一个, 也可能有一百个, 这都没有关系, 只要主题有一些要广播的消息就够了.
请记住, 事件驱动, 发布 - 订阅和观察者模式在实践中不是一回事, 但在理想情况下, 它们使用相同的方法: 一个实体广播一条消息, 其他实体侦听该消息.
发布 - 订阅模式和我一样老. 在 1987 年左右开始理论化, 而观察者模式则出现在 1994 年由 "四人帮" 所写的著作《设计模式》中.
事件驱动是怎样用在浏览器中的 JavaScript 的?
借助引擎, JavaScript 可以运行在你的浏览器中.
最受欢迎的 JavaScript 引擎是 Google Chrome 和 Node.JS 所使用的 V8,Firefox 的 SpiderMonkey 和 Safari/webKit 使用的 JavaScriptCore.
基于供丰富的环境, JavaScript 引擎增强了语言, 还提供了事件驱动的 JavaScript 平台.
实际上, 浏览器中的 JavaScript 可以与 html 元素进行交互, 这些 HTML 元素是事件发送器(event emitters), 即能够发送事件的对象.
思考一下这个简单的例子, 一个带有按钮的 HTML 文档:
- <!DOCTYPE HTML>
- <HTML>
- <head>
- <meta charset="UTF-8">
- <title>
- What means "event-driven" in JavaScript?
- </title>
- </head>
- <body>
- <div>
- <button id="subscribe">
- SUBSCRIBE
- </button>
- </div>
- </body>
- </HTML>
如果没有 JavaScript, 则这个按钮将毫无生命. 现在 HTML 按钮是 类型的元素, 并且与所有 HTML 元素一样, 它们都连接到 EventTarget -- 每个 HTML 元素的共同祖先.
浏览器中的事件目标是能够发出事件的对象: 它们是观察者模式中的主题.
有点混乱? 请记住: 主题是 FM 广播, 所以任何 HTML 元素都像是广电台.
一会儿, 你将看到谁是观察者.
浏览器中的主题和观察者
如果 HTML 元素是主题, 那么谁是观察者? 任何注册为侦听器的 JavaScript 函数都可以对浏览器中的事件做出反应.
使用 JavaScript 选择一个 HTML 元素:
const btn = document.getElementById('subscribe');
并使用 addEventListener 注册侦听器:
- const btn = document.getElementById('subscribe');
- btn.addEventListener("click", function () {
- console.log("Button clicked");
- });
这里的 "click" 是事件, 按钮是主题, 或者是发送器, 函数是侦听器, 或者是观察者.
回顾一下:
HTML 元素是事件发送器.
JavaScript 中注册为侦听器的函数是观察者.
所有这些组件构成了 " 一个小小的事件驱动的体系结构. 要测试代码请保存下面的 HTML 内容到文件(或在 Codepen 上尝试), 请单击按钮, 然后查看浏览器的控制台:
<!DOCTYPE HTML> <HTML> <head> <meta charset="UTF-8"> <title> What means "event-driven" in JavaScript? </title> </head> <body> <div> <button id="subscribe"> SUBSCRIBE </button> </div> </body> <script> const btn = document.getElementById('subscribe'); btn.addEventListener("click", function() { console.log("Button clicked"); }); </script> </HTML>
在下一部分中, 你将看到用于 Node.JS 的相同概念.
事件驱动如何用于 Node.JS?
Node.JS 是用于基于 V8 引擎的运行在浏览器之外 (命令行工具和服务器端) 的 JavaScript 环境.
你在 Node.JS 中所做的大部分工作都是基于事件的. 总会有一个发送器对象, 一些观察者在监听消息.
在 Node.JS 中, 没有任何 HTML 元素, 因此大多数事件都来自进程, 与网络的交互, 文件等.
Node.JS 中的每个事件发送器都有一个名为 on 的方法, 该方法至少需要两个参数:
要侦听的事件的名称
监听器函数
让我们举一个实际的例子. 看一下这个简单的 Node.JS 服务器:
const.NET = require("net"); const server = net.createServer().listen(8081, "127.0.0.1"); server.on("listening", function () { console.log("Server listening!"); }); server.on("connection", function (socket) { console.log("Client connected!"); socket.end("Hello client!"); });
这段代码创建了一个监听本地主机端口 8081 的服务器. 在 server 对象上, 我们调用 on 方法来注册两个侦听器函数.
服务器启动后立即触发 listening 事件, 而客户端连接到 127.0.0.1:8081 时将触发 connection 事件(尝试一下!).
在此示例中, server 是事件发送器, 主题. 另一方面, 侦听器函数是观察者.
但是那些 on 方法从哪里来的呢?
了解 EventEmitter
Node.JS 中的所有事件驱动模块都扩展了一个名为 EventEmitter 的根类. 在我们之前的例子中, 来自 net 模块的网络服务器就使用了 EventEmitter.
Node.JS 中的 EventEmitter 有两种基本方法: on 和 emit.
如果你想要与浏览器对应, 那么可以把 EventEmitter 看作是能够发出事件的任何一种 HTML 元素.
要在浏览器中侦听事件, 请在主题对象上调用 addEventListener:
const btn = document.getElementById('subscribe'); btn.addEventListener("click", function () { console.log("Button clicked"); });
相反, 在 Node.JS 中有 on:
// omit server.on("listening", () => { console.log("Server listening!"); }); // omit
准确地说, EventEmitter 上还有一个 addListener 方法. on 是它的别名.
EventEmitter 还有一个 emit 方法, 在你广播自定义事件 (消息) 时很有用.
如果要使用 EventEmitter , 请从 "events" 模块中导入并发出事件:
const EventEmitter = require("events"); const emitter = new EventEmitter(); emitter.on("customEvent", () => console.log("Got event!")); emitter.emit("customEvent");
用 Node.JS 运行代码, 你将在控制台中看到 "Got event".
JavaScript 中有关观察者 / 发布 - 订阅的其他示例
JavaScript 没有对观察者对象的原生支持, 但是有人建议将其添加到语言中.
RxJS http://reactivex.io/ 是一个将观察者模式引入 JavaScript 的库.
Redux https://www.valentinog.com/blog/redux/ 是 JavaScript 中发布 - 订阅模式的实现. 这是一个非常好的事件发送器, 其中状态的更改会被分发给所有监听的观察者.
现代浏览器附带 Intersection Observer API, 这是观察者模式的另一个例子.
Socket.IO 是一个库, 大量使用了事件.
总结
希望你从这篇文章中学到新的东西. 你学到了很多术语, 但最终都归结为大约 30 年前发明的模式: 发布 - 订阅.
这种模式, 也称为观察者, 是我们今天在 JavaScript 和 Node.JS 中所使用的事件驱动架构的基础.
再次强调, 事件驱动, 发布 - 订阅和观察者的模式并非完全相同: 事件驱动的体系结构建立在发布 - 订阅之上, 观察者模式比 DOM 和 Node.JS 事件更丰富.
但他们都是属于同一个家庭的成员.
来源: http://www.css88.com/web/javascript/16493.html