精华内容
下载资源
问答
  • 事件驱动程序设计

    2021-02-25 08:51:20
    运行java图形用户界面程序时,程序与用户进行交互,事件驱动程序的执行.事件(event)可以定义为程序发生了某些事情的信号.外部用户动作和内部程序动作都可以触发事件,外部用户动作的例子有移动鼠标,点击按钮和敲击键盘...
  • Java事件驱动程序设计相关程序源代码,包括事件和事件源、事件的监听、注册和处理、内部类监听器、匿名内部类监听器、处理简单行为的事件、处理窗口事件、监听器接口适配器、鼠标事件、键盘事件、使用Timer类的动画...
  • nodeJs之事件驱动程序

    千次阅读 2018-06-03 23:09:41
    事件驱动程序 Node.js 使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。 当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。 这个模型非常...

    事件驱动程序

    Node.js 使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。

    当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。

    这个模型非常高效可扩展性非常强,因为webserver一直接受请求而不等待任何读写操作。(这也被称之为非阻塞式IO或者事件驱动IO)

    在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。

    整个事件驱动的流程就是这么实现的,非常简洁。有点类似于观察者模式,事件相当于一个主题(Subject),而所有注册到这个事件上的处理函数相当于观察者(Observer)。

    // 引入 events 模块
    var events = require('events');
    // 创建 eventEmitter 对象
    var eventEmitter = new events.EventEmitter();

    以下程序绑定事件处理程序:

    // 绑定事件及事件的处理程序
    eventEmitter.on('eventName', eventHandler);

    我们可以通过程序触发事件:

    // 触发事件
    eventEmitter.emit('eventName');


    // 引入 events 模块
    var events = require('events');
    // 创建 eventEmitter 对象
    var eventEmitter = new events.EventEmitter();
    
    // 创建事件处理程序
    var connectHandler = function connected() {
       console.log('连接成功。');
      
       // 触发 data_received 事件 
       eventEmitter.emit('data_received');
    }
    
    // 绑定 connection 事件处理程序
    eventEmitter.on('connection', connectHandler);
     
    // 使用匿名函数绑定 data_received 事件
    eventEmitter.on('data_received', function(){
       console.log('数据接收成功。');
    });
    
    // 触发 connection 事件 
    eventEmitter.emit('connection');
    
    console.log("程序执行完毕。");

    Node.js EventEmitter

    Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列。

    Node.js里面的许多对象都会分发事件:一个net.Server对象会在每次有新连接时分发一个事件, 一个fs.readStream对象会在文件被打开的时候发出一个事件。 所有这些产生事件的对象都是 events.EventEmitter 的实例。


    EventEmitter 类

    events 模块只提供了一个对象: events.EventEmitter。EventEmitter 的核心就是事件触发与事件监听器功能的封装。

    你可以通过require("events");来访问该模块。

    // 引入 events 模块
    var events = require('events');
    // 创建 eventEmitter 对象
    var eventEmitter = new events.EventEmitter();

    EventEmitter 对象如果在实例化时发生错误,会触发 error 事件。当添加新的监听器时,newListener 事件会触发,当监听器被移除时,removeListener 事件被触发。

    下面我们用一个简单的例子说明 EventEmitter 的用法:

    //event.js 文件
    var EventEmitter = require('events').EventEmitter; 
    var event = new EventEmitter(); 
    event.on('some_event', function() { 
        console.log('some_event 事件触发'); 
    }); 
    setTimeout(function() { 
        event.emit('some_event'); 
    }, 1000); 

    执行结果如下:

    运行这段代码,1 秒后控制台输出了 'some_event 事件触发'。其原理是 event 对象注册了事件 some_event 的一个监听器,然后我们通过 setTimeout 在 1000 毫秒以后向 event 对象发送事件 some_event,此时会调用some_event 的监听器。

    $ node event.js 
    some_event 事件触发

    EventEmitter 的每个事件由一个事件名和若干个参数组成,事件名是一个字符串,通常表达一定的语义。对于每个事件,EventEmitter 支持 若干个事件监听器。

    当事件触发时,注册到这个事件的事件监听器被依次调用,事件参数作为回调函数参数传递。

    让我们以下面的例子解释这个过程:

    //event.js 文件
    var events = require('events'); 
    var emitter = new events.EventEmitter(); 
    emitter.on('someEvent', function(arg1, arg2) { 
        console.log('listener1', arg1, arg2); 
    }); 
    emitter.on('someEvent', function(arg1, arg2) { 
        console.log('listener2', arg1, arg2); 
    }); 
    emitter.emit('someEvent', 'arg1 参数', 'arg2 参数'); 

    执行以上代码,运行的结果如下:

    $ node event.js 
    listener1 arg1 参数 arg2 参数
    listener2 arg1 参数 arg2 参数

    以上例子中,emitter 为事件 someEvent 注册了两个事件监听器,然后触发了 someEvent 事件。

    运行结果中可以看到两个事件监听器回调函数被先后调用。 这就是EventEmitter最简单的用法。

    EventEmitter 提供了多个属性,如 on 和 emiton 函数用于绑定事件函数,emit 属性用于触发一个事件。接下来我们来具体看下 EventEmitter 的属性介绍。

    方法

    序号方法 & 描述
    1addListener(event, listener)
    为指定事件添加一个监听器到监听器数组的尾部。
    2on(event, listener)
    为指定事件注册一个监听器,接受一个字符串 event 和一个回调函数。
    server.on('connection', function (stream) {
      console.log('someone connected!');
    });
    3once(event, listener)
    为指定事件注册一个单次监听器,即 监听器最多只会触发一次,触发后立刻解除该监听器。
    server.once('connection', function (stream) {
      console.log('Ah, we have our first user!');
    });
    4removeListener(event, listener)

    移除指定事件的某个监听器,监听器必须是该事件已经注册过的监听器。

    它接受两个参数,第一个是事件名称,第二个是回调函数名称。

    var callback = function(stream) {
      console.log('someone connected!');
    };
    server.on('connection', callback);
    // ...
    server.removeListener('connection', callback);
    5removeAllListeners([event])
    移除所有事件的所有监听器, 如果指定事件,则移除指定事件的所有监听器。
    6setMaxListeners(n)
    默认情况下, EventEmitters 如果你添加的监听器超过 10 个就会输出警告信息。 setMaxListeners 函数用于提高监听器的默认限制的数量。
    7listeners(event)
    返回指定事件的监听器数组。
    8emit(event, [arg1], [arg2], [...])
    按参数的顺序执行每个监听器,如果事件有注册监听返回 true,否则返回 false。

    类方法

    序号方法 & 描述
    1listenerCount(emitter, event)
    返回指定事件的监听器数量。

    事件

    序号事件 & 描述
    1newListener
    • event - 字符串,事件名称

    • listener - 处理事件函数

    该事件在添加新监听器时被触发。

    2removeListener
    • event - 字符串,事件名称

    • listener - 处理事件函数

    从指定监听器数组中删除一个监听器。需要注意的是,此操作将会改变处于被删监听器之后的那些监听器的索引。

    实例

    以下实例通过 connection(连接)事件演示了 EventEmitter 类的应用。

    创建 main.js 文件,代码如下:

    var events = require('events');
    var eventEmitter = new events.EventEmitter();
    
    // 监听器 #1
    var listener1 = function listener1() {
       console.log('监听器 listener1 执行。');
    }
    
    // 监听器 #2
    var listener2 = function listener2() {
      console.log('监听器 listener2 执行。');
    }
    
    // 绑定 connection 事件,处理函数为 listener1 
    eventEmitter.addListener('connection', listener1);
    
    // 绑定 connection 事件,处理函数为 listener2
    eventEmitter.on('connection', listener2);
    
    var eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
    console.log(eventListeners + " 个监听器监听连接事件。");
    
    // 处理 connection 事件 
    eventEmitter.emit('connection');
    
    // 移除监绑定的 listener1 函数
    eventEmitter.removeListener('connection', listener1);
    console.log("listener1 不再受监听。");
    
    // 触发连接事件
    eventEmitter.emit('connection');
    
    eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
    console.log(eventListeners + " 个监听器监听连接事件。");
    
    console.log("程序执行完毕。");

    以上代码,执行结果如下所示:

    $ node main.js
    2 个监听器监听连接事件。
    监听器 listener1 执行。
    监听器 listener2 执行。
    listener1 不再受监听。
    监听器 listener2 执行。
    1 个监听器监听连接事件。
    程序执行完毕。

    error 事件

    EventEmitter 定义了一个特殊的事件 error,它包含了错误的语义,我们在遇到 异常的时候通常会触发 error 事件。

    当 error 被触发时,EventEmitter 规定如果没有响 应的监听器,Node.js 会把它当作异常,退出程序并输出错误信息。

    我们一般要为会触发 error 事件的对象设置监听器,避免遇到错误后整个程序崩溃。例如:

    var events = require('events'); 
    var emitter = new events.EventEmitter(); 
    emitter.emit('error'); 

    运行时会显示以下错误:

    node.js:201 
    throw e; // process.nextTick error, or 'error' event on first tick 
    ^ 
    Error: Uncaught, unspecified 'error' event. 
    at EventEmitter.emit (events.js:50:15) 
    at Object.<anonymous> (/home/byvoid/error.js:5:9) 
    at Module._compile (module.js:441:26) 
    at Object..js (module.js:459:10) 
    at Module.load (module.js:348:31) 
    at Function._load (module.js:308:12) 
    at Array.0 (module.js:479:10) 
    at EventEmitter._tickCallback (node.js:192:40) 

    继承 EventEmitter

    大多数时候我们不会直接使用 EventEmitter,而是在对象中继承它。包括 fs、net、 http 在内的,只要是支持事件响应的核心模块都是 EventEmitter 的子类。

    为什么要这样做呢?原因有两点:

    首先,具有某个实体功能的对象实现事件符合语义, 事件的监听和发生应该是一个对象的方法。

    其次 JavaScript 的对象机制是基于原型的,支持 部分多重继承,继承 EventEmitter 不会打乱对象原有的继承关系


    Node.js是基于V8引擎实现的事件驱动无阻塞IO构架,Node.js能够在众多的后端JavaScript技术之中脱颖而出,正是因其基于事件的特点而受到欢迎。
    这里主要介绍如何使用EventEmitter类来实现事件的发送与接收。

    原型继承法
    虽然,原型继承经常被视作 JavaScript 的一个弱点,但事实上,原型继承模型比经典的继承模型更强大。举例来说,在原型继承模型的基础之上建立一个经典的继承模型是相当容易的。
    JavaScript 对象是动态的属性“包”(指其自己的属性)。JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依此层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。
    通过原型链实现继承:
    var EventEmitter  = require('events').EventEmitter
    function Client() {
      EventEmitter.call(this);
    }
    Client.prototype.auth = function() {
      console.log('arguments')
    }
    
    Client.prototype.__proto__ = EventEmitter.prototype;
    
    var client = new Client();
    
    //接收事件
    client.on('auth', client.auth)
    //发送事件
    client.emit('auth')

    类继承法

    ES6提供了class和 extends两个关键字来实现继承,相对于原型继承。虽然只是语法糖,但它的语法确实更为简洁,也更符合面向对象语言的语法习惯。
    var EventEmitter  = require('events').EventEmitter
    
    class Client extends EventEmitter {
      constructor() {
        super()
      }
      auth() {
      	console.log('arguments')
      }
    }
    
    let client = new Client()
    
    //接收事件
    client.on('auth', client.auth)
    //发送事件
    client.emit('auth')


    对象继承法

    有时侯你也许并不需要创建一个类,而只需要对某个对象添加对象收发机制,此时只需要重新指定原型链即可。
    var EventEmitter  = require('events').EventEmitter
    
    var client = {
      auth() {
        console.log('arguments')
      }
    };
    
    client.__proto__ = EventEmitter.prototype;
    
    // Subscribe to event.
    client.on("auth", client.auth);
    // Emit event.
    client.emit("auth");



    展开全文
  • 内容索引:Java源码,初学实例,事件驱动 Java事件驱动程序设计相关程序源代码,包括事件和事件源、事件的监听、注册和处理、内部类监听器、匿名内部类监听器、处理简单行为的事件、处理窗口事件、监听器接口适配器、...
  • 用于在单例应用程序Grafka上应用事件驱动程序体系结构的Grandjs程序包帮助程序用于在单项应用程序上应用事件驱动程序体系结构的Grandjs程序包帮助程序内容Grafka内容关于功能用例先决条件依赖项安装用法体系结构...
  • 傻瓜 Java 中的事件驱动程序
  • 采用基于事件驱动模型进行程序设计,其实现步骤包括以下5个步骤 (1)定义事件相关信息类。 (2)在事件发布者类(事件源)中声明事件,并声明一个负责触发事件的方法。 (3)在事件接收者类中声明事件产生时调用...

    采用基于事件驱动模型进行程序设计,其实现步骤包括以下5个步骤

    (1)定义事件相关信息类。

    (2)在事件发布者类(事件源)中声明事件,并声明一个负责触发事件的方法。

    (3)在事件接收者类中声明事件产生时调用的方法。

    (4)在事件接收者类中订阅事件。

    *在用户界面中订阅事件,也就是调用负责预定事件的方法。(*根据实际情况有无此步骤)

    (5)在事件接收者类中触发事件。

    展开全文
  • 它旨在用于构建事件驱动的应用程序,启用事件源,消息上的RPC,sagas以及Watermill基本上提供的其他功能Watermill是一个Go库,用于有效地处理消息流。 它旨在用于构建事件驱动的应用程序,启用事件源,消息上的RPC,...
  • [Java]事件驱动程序设计

    千次阅读 2017-03-14 13:37:51
    事件驱动模型三大要素 1)事件源:能接收外部事件的源体; 2)监听器xListener:能接收事件源通知的对象; 3)处理器Handler:用于处理事件的对象。 在Java中使用监听器对象处理事件的方式,称为委托事件模型。
    • 事件驱动模型三大要素
      1)事件源:能接收外部事件的源体;
      2)监听器xListener:能接收事件源通知的对象;
      3)处理器Handler:用于处理事件的对象。

    • 在Java中使用监听器对象处理事件的方式,称为委托事件模型。

    展开全文
  • C语言实现,用于嵌入式尤其单片机系统,小巧简单易用的事件驱动型按键驱动模块,可无限量扩展按键,按键事件的回调异步处理方式可以简化你的程序结构,按键业务逻辑更清晰。c语言源代码;修订了原版的bug,更易用。...
  • 本文档是严蔚敏版《数据结构》第65页的那个例子:银行客户的离散事件驱动模拟程序,用C语言实现,已在VC++6.0环境下编译运行,无误!
  • 此文件描述了ucos下程序设计的思路,仅供参考.众所周知,windows下的程序是以事件驱动的方式工作的,于是想到有没有一种方法可以再ucos上也实现这种方法.
  • 摘要:通过实例说明将事件驱动机制应用到单片机程序中,使中断响应与处理程序分离,可较理想地用硬件定时代替处理程序中的软件定时,从而大幅提高系统对多中断的实时响应能力,降低多中断系统调试的难度。...
  • 一个很好的基于事件驱动单片机程序设计,源码开发,是开发的很好的参考
  • 文章论述了有限状态机理论,结合软件分层的结构思想,详细分析了事件驱动程序设计方法。结合实际项目油田原油油量计量 和防盗系统,分析了该系统远程监测终端软件的层次结构,系统状态和事件的划分方法,给出了...
  • 事件驱动的详解

    万次阅读 多人点赞 2019-01-21 14:58:58
    事件驱动和异步IO 通常,我们写服务器处理模型的程序时,有以下几种模型: (1)每收到一个请求,创建一个新的进程,来处理该请求; (2)每收到一个请求,创建一个新的线程,来处理该请求; (3)每收到一个请求,...

    事件驱动和异步IO

    通常,我们写服务器处理模型的程序时,有以下几种模型:
    (1)每收到一个请求,创建一个新的进程,来处理该请求;
    (2)每收到一个请求,创建一个新的线程,来处理该请求;
    (3)每收到一个请求,放入一个事件列表,让主进程通过非阻塞I/O方式来处理请求
    上面的几种方式,各有千秋,
    第(1)中方法,由于创建新的进程的开销比较大,所以,会导致服务器性能比较差,但实现比较简单。
    第(2)种方式,由于要涉及到线程的同步,有可能会面临死锁等问题。
    第(3)种方式,在写应用程序代码时,逻辑比前面两种都复杂。
    综合考虑各方面因素,一般普遍认为第(3)种方式是大多数网络服务器采用的方式
     


    看图说话讲事件驱动模型 


    在UI编程中,常常要对鼠标点击进行相应,首先如何获得鼠标点击呢?
    方式一:创建一个线程,该线程一直循环检测是否有鼠标点击,那么这个方式有以下几个缺点:
    1. CPU资源浪费,可能鼠标点击的频率非常小,但是扫描线程还是会一直循环检测,这会造成很多的CPU资源浪费;如果扫描鼠标点击的接口是阻塞的呢?
    2. 如果是堵塞的,又会出现下面这样的问题,如果我们不但要扫描鼠标点击,还要扫描键盘是否按下,由于扫描鼠标时被堵塞了,那么可能永远不会去扫描键盘;
    3. 如果一个循环需要扫描的设备非常多,这又会引来响应时间的问题;
    所以,该方式是非常不好的。

    方式二:就是事件驱动模型
    目前大部分的UI编程都是事件驱动模型,如很多UI平台都会提供onClick()事件,这个事件就代表鼠标按下事件。事件驱动模型大体思路如下:
    1. 有一个事件(消息)队列;
    2. 鼠标按下时,往这个队列中增加一个点击事件(消息);
    3. 有个循环,不断从队列取出事件,根据不同的事件,调用不同的函数,如onClick()、onKeyDown()等;
    4. 事件(消息)一般都各自保存各自的处理函数指针,这样,每个消息都有独立的处理函数;


    事件驱动编程是一种编程范式,这里程序的执行流由外部事件来决定。它的特点是包含一个事件循环,当外部事件发生时使用回调机制来触发相应的处理。另外两种常见的编程范式是(单线程)同步以及多线程编程。

    让我们用例子来比较和对比一下单线程、多线程以及事件驱动编程模型。下图展示了随着时间的推移,这三种模式下程序所做的工作。这个程序有3个任务需要完成,每个任务都在等待I/O操作时阻塞自身。阻塞在I/O操作上所花费的时间已经用灰色框标示出来了。

    在单线程同步模型中,任务按照顺序执行。如果某个任务因为I/O而阻塞,其他所有的任务都必须等待,直到它完成之后它们才能依次执行。这种明确的执行顺序和串行化处理的行为是很容易推断得出的。如果任务之间并没有互相依赖的关系,但仍然需要互相等待的话这就使得程序不必要的降低了运行速度。

    在多线程版本中,这3个任务分别在独立的线程中执行。这些线程由操作系统来管理,在多处理器系统上可以并行处理,或者在单处理器系统上交错执行。这使得当某个线程阻塞在某个资源的同时其他线程得以继续执行。与完成类似功能的同步程序相比,这种方式更有效率,但程序员必须写代码来保护共享资源,防止其被多个线程同时访问。多线程程序更加难以推断,因为这类程序不得不通过线程同步机制如锁、可重入函数、线程局部存储或者其他机制来处理线程安全问题,如果实现不当就会导致出现微妙且令人痛不欲生的bug。

    在事件驱动版本的程序中,3个任务交错执行,但仍然在一个单独的线程控制中。当处理I/O或者其他昂贵的操作时,注册一个回调到事件循环中,然后当I/O操作完成时继续执行。回调描述了该如何处理某个事件。事件循环轮询所有的事件,当事件到来时将它们分配给等待处理事件的回调函数。这种方式让程序尽可能的得以执行而不需要用到额外的线程。事件驱动型程序比多线程程序更容易推断出行为,因为程序员不需要关心线程安全问题。

    当我们面对如下的环境时,事件驱动模型通常是一个好的选择:

    程序中有许多任务,而且…
    任务之间高度独立(因此它们不需要互相通信,或者等待彼此)而且…
    在等待事件到来时,某些任务会阻塞。
    当应用程序需要在任务间共享可变的数据时,这也是一个不错的选择,因为这里不需要采用同步处理。

    网络应用程序通常都有上述这些特点,这使得它们能够很好的契合事件驱动编程模型。
    --------------------- 
    作者:rainyday66 
    来源:CSDN 
    原文:https://blog.csdn.net/qq_34173549/article/details/80212101 
    版权声明:本文为博主原创文章,转载请附上博文链接!

    展开全文
  • 实时性和可靠性已经通过示波器监视时序的测试(在系统负荷较高的情况下),这是可执行程序代码。
  • 使用内部类或者匿名内部类定义监听类已经成了事件处理程序设计的标准。 因为他通常都能提供清晰、干净和简洁的代码。 package chapter16; import java.awt.FlowLayout; import java.awt.event...
  • 关于事件驱动编程

    千次阅读 2017-04-21 14:00:06
    关于事件驱动编程全世界最熟悉事件驱动的程序员应该就是前端工程师了,不管是桌面前端还是web前端都是世界上最熟悉事件驱动的,以web前端为例,我们作业面可以不去想什么面向对象编程,什么jQuery框架咋用,但是为按钮,为...
  • 什么是事件驱动

    千次阅读 2018-03-07 23:23:58
    实际上,现代的程序大多是事件驱动的,比如多线程的程序,肯定是事件驱动的。早期则存在许多非事件驱动程序,这样的程序,在需要等待某个条件触发时,会不断地检查这个条件,直到条件满足,这是很浪费cpu时间的。...
  • 所有的计算机程序都可以大致分为两类:...我们要开发的交易系统就是属于连续运行型程序,而这种程序根据其计算逻辑的运行机制不同,又可以粗略的分为时间驱动和事件驱动两种。 1.1 时间驱动 时间驱动的程序逻辑相对容
  • 点击文字 鼠标拖动 文字会随鼠标拖动 package chapter16; import java.awt.BorderLayout; import java.awt.Graphics; import java.awt.event.MouseEvent;...import java.awt.event.MouseMotionListener;...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 261,438
精华内容 104,575
关键字:

事件驱动程序