精华内容
下载资源
问答
  • nodejs事件和事件循环详解

    千次阅读 2021-01-14 16:40:41
    上篇文章我们简单的介绍了nodejs中的事件event和事件循环event loop。本文本文将会更进一步,继续讲解nodejs中的event,并探讨一下setTimeout,setImmediateprocess.nextTick的区别。

    简介

    上篇文章我们简单的介绍了nodejs中的事件event和事件循环event loop。本文本文将会更进一步,继续讲解nodejs中的event,并探讨一下setTimeout,setImmediate和process.nextTick的区别。

    nodejs中的事件循环

    虽然nodejs是单线程的,但是nodejs可以将操作委托给系统内核,系统内核在后台处理这些任务,当任务完成之后,通知nodejs,从而触发nodejs中的callback方法。

    这些callback会被加入轮循队列中,最终被执行。

    通过这样的event loop设计,nodejs最终可以实现非阻塞的IO。

    nodejs中的event loop被分成了一个个的phase,下图列出了各个phase的执行顺序:

    每个phase都会维护一个callback queue,这是一个FIFO的队列。

    当进入一个phase之后,首先会去执行该phase的任务,然后去执行属于该phase的callback任务。

    当这个callback队列中的任务全部都被执行完毕或达到了最大的callback执行次数之后,就会进入下一个phase。

    注意, windows和linux的具体实现有稍许不同,这里我们只关注最重要的几个phase。

    问题:phase的执行过程中,为什么要限制最大的callback执行次数呢?

    回答:在极端情况下,某个phase可能会需要执行大量的callback,如果执行这些callback花费了太多的时间,那么将会阻塞nodejs的运行,所以我们设置callback执行的次数限制,以避免nodejs的长时间block。

    phase详解

    上面的图中,我们列出了6个phase,接下来我们将会一一的进行解释。

    timers

    timers的中文意思是定时器,也就是说在给定的时间或者时间间隔去执行某个callback函数。

    通常的timers函数有这样两种:setTimeout和setInterval。

    一般来说这些callback函数会在到期之后尽可能的执行,但是会受到其他callback执行的影响。 我们来看一个例子:

    const fs = require('fs');
    
    function someAsyncOperation(callback) {
      // Assume this takes 95ms to complete
      fs.readFile('/path/to/file', callback);
    }
    
    const timeoutScheduled = Date.now();
    
    setTimeout(() => {
      const delay = Date.now() - timeoutScheduled;
    
      console.log(`${delay}ms have passed since I was scheduled`);
    }, 100);
    
    // do someAsyncOperation which takes 95 ms to complete
    someAsyncOperation(() => {
      const startCallback = Date.now();
    
      // do something that will take 10ms...
      while (Date.now() - startCallback < 10) {
        // do nothing
      }
    });
    

    上面的例子中,我们调用了someAsyncOperation,这个函数首先回去执行readFile方法,假设这个方法耗时95ms。接着执行readFile的callback函数,这个callback会执行10ms。最后才回去执行setTimeout中的callback。

    所以上面的例子中,虽然setTimeout指定要在100ms之后运行,但是实际上还要等待95 + 10 = 105 ms之后才会真正的执行。

    pending callbacks

    这个phase将会执行一些系统的callback操作,比如在做TCP连接的时候,TCP socket接收到了ECONNREFUSED信号,在某些liunx操作系统中将会上报这个错误,那么这个系统的callback将会放到pending callbacks中运行。

    或者是需要在下一个event loop中执行的I/O callback操作。

    idle, prepare

    idle, prepare是内部使用的phase,这里就不过多介绍。

    poll轮询

    poll将会检测新的I/O事件,并执行与I / O相关的回调,注意这里的回调指的是除了关闭callback,timers,和setImmediate之外的几乎所有的callback事件。

    poll主要处理两件事情:轮询I/O,并且计算block的时间,然后处理poll queue中的事件。

    如果poll queue非空的话,event loop将会遍历queue中的callback,然后一个一个的同步执行,知道queue消费完毕,或者达到了callback数量的限制。

    因为queue中的callback是一个一个同步执行的,所以可能会出现阻塞的情况。

    如果poll queue空了,如果代码中调用了setImmediate,那么将会立马跳到下一个check phase,然后执行setImmediate中的callback。 如果没有调用setImmediate,那么会继续等待新来的callback被加入到queue中,并执行。

    check

    主要来执行setImmediate的callback。

    setImmediate可以看做是一个运行在单独phase中的独特的timer,底层使用的libuv API来规划callbacks。

    一般来说,如果在poll phase中有callback是以setImmediate的方式调用的话,会在poll queue为空的情况下,立马结束poll phase,进入check phase来执行对应的callback方法。

    close callbacks

    最后一个phase是处理close事件中的callbacks。 比如一个socket突然被关闭,那么将会触发一个close事件,并调用相关的callback。

    setTimeout 和 setImmediate的区别

    setTimeout和setImmediate有什么不同呢?

    从上图的phase阶段可以看出,setTimeout中的callback是在timer phase中执行的,而setImmediate是在check阶段执行的。

    从语义上讲,setTimeout指的是,在给定的时间之后运行某个callback。而setImmediate是在执行完当前loop中的 I/O操作之后,立马执行。

    那么这两个方法的执行顺序上有什么区别呢?

    下面我们举两个例子,第一个例子中两个方法都是在主模块中运行:

    setTimeout(() => {
      console.log('timeout');
    }, 0);
    
    setImmediate(() => {
      console.log('immediate');
    });
    

    这样运行两个方法的执行顺序是不确定,因为可能受到其他执行程序的影响。

    第二个例子是在I/O模块中运行这两个方法:

    const fs = require('fs');
    
    fs.readFile(__filename, () => {
      setTimeout(() => {
        console.log('timeout');
      }, 0);
      setImmediate(() => {
        console.log('immediate');
      });
    });
    

    你会发现,在I/O模块中,setImmediate一定会在setTimeout之前执行。

    两者的共同点

    setTimeout和setImmediate两者都有一个返回值,我们可以通过这个返回值,来对timer进行clear操作:

    const timeoutObj = setTimeout(() => {
      console.log('timeout beyond time');
    }, 1500);
    
    const immediateObj = setImmediate(() => {
      console.log('immediately executing immediate');
    });
    
    const intervalObj = setInterval(() => {
      console.log('interviewing the interval');
    }, 500);
    
    clearTimeout(timeoutObj);
    clearImmediate(immediateObj);
    clearInterval(intervalObj);
    

    clear操作也可以clear intervalObj。

    unref 和 ref

    setTimeout和setInterval返回的对象都是Timeout对象。

    如果这个timeout对象是最后要执行的timeout对象,那么可以使用unref方法来取消其执行,取消执行完毕,可以使用ref来恢复它的执行。

    const timerObj = setTimeout(() => {
      console.log('will i run?');
    });
    
    timerObj.unref();
    
    setImmediate(() => {
      timerObj.ref();
    });
    

    注意,如果有多个timeout对象,只有最后一个timeout对象的unref方法才会生效。

    process.nextTick

    process.nextTick也是一种异步API,但是它和timer是不同的。

    如果我们在一个phase中调用process.nextTick,那么nextTick中的callback会在这个phase完成,进入event loop的下一个phase之前完成。

    这样做就会有一个问题,如果我们在process.nextTick中进行递归调用的话,这个phase将会被阻塞,影响event loop的正常执行。

    那么,为什么我们还会有process.nextTick呢?

    考虑下面的一个例子:

    let bar;
    
    function someAsyncApiCall(callback) { callback(); }
    
    someAsyncApiCall(() => {
      console.log('bar', bar); // undefined
    });
    
    bar = 1;
    

    上面的例子中,我们定义了一个someAsyncApiCall方法,里面执行了传入的callback函数。

    这个callback函数想要输出bar的值,但是bar的值是在someAsyncApiCall方法之后被赋值的。

    这个例子最终会导致输出的bar值是undefined。

    我们的本意是想让用户程序执行完毕之后,再调用callback,那么我们可以使用process.nextTick来对上面的例子进行改写:

    let bar;
    
    function someAsyncApiCall(callback) {
      process.nextTick(callback);
    }
    
    someAsyncApiCall(() => {
      console.log('bar', bar); // 1
    });
    
    bar = 1;
    

    我们再看一个实际中使用的例子:

    const server = net.createServer(() => {}).listen(8080);
    
    server.on('listening', () => {});
    

    上面的例子是最简单的nodejs创建web服务。

    上面的例子有什么问题呢?listen(8000) 方法将会立马绑定8000端口。但是这个时候,server的listening事件绑定代码还没有执行。

    这里实际上就用到了process.nextTick技术,从而不管我们在什么地方绑定listening事件,都可以监听到listen事件。

    process.nextTick 和 setImmediate 的区别

    process.nextTick 是立马在当前phase执行callback,而setImmediate是在check阶段执行callback。

    所以process.nextTick要比setImmediate的执行顺序优先。

    实际上,process.nextTick和setImmediate的语义应该进行互换。因为process.nextTick表示的才是immediate,而setImmediate表示的是next tick。

    本文作者:flydean程序那些事

    本文链接:http://www.flydean.com/nodejs-event-more/

    本文来源:flydean的博客

    欢迎关注我的公众号:「程序那些事」最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

    展开全文
  • 事件绑定普通事件什么区别

    千次阅读 2019-05-07 08:46:55
    事件绑定普通事件什么区别 传统事件绑定符合 W3C 标准的事件绑定有什么区别? div1.οnclick=function(){}; 1、如果说给同一个元素绑定了两次或者多次相同类型的事件,那么后面的绑定会覆盖前面 的绑定 2、不...

    事件绑定和普通事件有什么区别

    传统事件绑定和符合 W3C 标准的事件绑定有什么区别?

    div1.οnclick=function(){};
    1、如果说给同一个元素绑定了两次或者多次相同类型的事件,那么后面的绑定会覆盖前面 的绑定
    2、不支持 DOM 事件流 事件捕获阶段目标元素阶段=>事件冒泡阶段
    addEventListener
    1、 如果说给同一个元素绑定了两次或者多次相同类型的事件,所有的绑定将会依次触发 2、 支持 DOM 事件流的 3、 进行事件绑定传参不需要 on 前缀 addEventListener(“click”,function(){},true);//此时的事件就是在事件冒泡阶段执行
    ie9 开始,ie11edge:addEventListener
    ie9 以前:attachEvent/detachEvent
    1、 进行事件类型传参需要带上 on 前缀 2、 这种方式只支持事件冒泡,不支持事件捕获 事件绑定是指把事件注册到具体的元素之上,普通事件指的是可以用来注册的事件

    展开全文
  • 事件中的sender是什么意思

    万次阅读 2014-05-11 13:24:54
    以上代码是一个按钮的点击事件,在其他事件中也会发现有一个sender参数,那么这个参数代表什么意思呢?又有怎样的作用?下面就以按钮为例进行说明。 sender:指触发事件的控件,之所以是object类型,是因为...

    感谢《传智播客》提供的视频


    以WPF为例进行讲解


    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
    
    }


    以上代码是一个按钮的点击事件,在其他事件中也会发现有一个sender参数,那么这个参数代表什么意思呢?又有怎样的作用?下面就以按钮为例进行说明。


    sender:指触发事件的控件,之所以是object类型,是因为button按钮也是一个类,命名空间:System.Windows.Controls。所以讲所有将触发类型的控件定义为object类。object为所有类型的基类


    那么怎么在代码中得到当前的控件?看下面的代码。

            private void Button_Click_1(object sender, RoutedEventArgs e)
            {
                Button btn = (Button)sender;//将sender进行转换,转换成按钮对象。
                btn.Content = "你点我了";//设置按钮的文本为“你点我了”
            }

    在没有点击按钮之前的显示:



    点击按钮之后的显示:



    那么这样的话就会存在一个疑问,下面的代码同样可以实现这样的功能,为什么还要按照上边的那么写呢?


            private void Button_Click_1(object sender, RoutedEventArgs e)
            {
                //Button btn = (Button)sender;
                //btn.Content = "你点我了";
                btn1.Content = "你点我了";//btn1为按钮的名字
            }

    疑问解答:

    现在需要100个按钮都要实现上边的功能,按照常规的写法就要写100个对应的事件,sender就可以解决这样的问题。

    同样,我们在窗体中再添加一个按钮(100个太多了,实践的话使用两个即可)名字为btn2,

    接下来设置这个按钮的Click事件,让它在执行时运行Button_Click_1事件,如图:



    这样就实现了上述的功能,无需书写100个事件。


    以此为基础我们可以对控件进行封装方法




    展开全文
  • 关于jquery中 的点击事件,每点一次执行的效果就叠加一次,click是添加点击事件意思

    我本人还是前端的菜鸟,所以一般在写特效的时候,喜欢用jquery,但是在用jquery的点击事件中,点击后改变容器中的内容,但是发现每点一次就显示一个内容,点几次就有几个。jquery中 的点击事件,每点一次执行的效果就叠加一次,click是添加点击事件的意思。那么来解决这个问题:


    我们在点击事件前,先解绑,那么就不会实现每次添加一次了

    展开全文
  • 既然复制了节点了 为什么属性、事件不会被复制过去, 那么复制节点到底是复制了什么过去?
  • 事件监听: 为同一个对象的同一个事件绑定多个事件处理程序 事件绑定: 对DOM元素绑定事件处理函数 一般分为三种 1、在DOM元素中直接绑定 2、在js中绑定 3、绑定事件监听函数 事件委托: 利用冒泡的原理,把事件加到...
  • 当你的手指(或者其它)移动屏幕的时候会触发这个事件,比如当你的手指在屏幕上拖动一个listView或者一个ScrollView而不是去按上面的按钮时会触发这个事件。 在设计设置页面的滑动开关时,如果...
  • 彻底弄懂JS的事件冒泡和事件捕获

    千次阅读 2017-03-05 20:25:49
    他们是描述事件触发时序问题的术语。事件捕获指的是从document到触发事件的那个节点,即自上而下的去触发事件。...Jquery的e.stopPropagation会阻止冒泡,意思就是到我为止,我的爹祖宗的事件就不要触发了。 这...
  • LTE的A1事件A2事件A3事件A4事件指的都是什么? 转自:https://baike.1688.com/doc/view-d40621976.htmlLTE切换时需要UE上报测量的结果(包括RSRP,RSRQ等),而上报又分为周期性上报和事件触发的上报。周期性上报由...
  • JS事件绑定(addEventListener)普通事件(onclick)有什么区别 普通事件(onclick) 普通事件就是直接触发事件,同一时间只能指向唯一对象,所以会被覆盖掉。代码如下: var btn = document.getElementById("btn...
  • 什么要区分元素的click事件和mousedown、mouseup事件? 在使用js实现元素可拖拽效果时,需要监听鼠标的mouseup、mousedown事件,当拖拽的元素本身需要绑定一个click点击事件时,这种情景下就需要对用户是拖拽操作...
  • 定义 事件是指被程序发现的行为或发生的事情,而且它可能会被程序处理。 MV*框架通常区分两种事件: ...用户事件:通常在view中...程序事件:应用自身也可以触发处理一些事件,比如渲染后触发onRender事件等。
  • 什么事件时间处理时间?

    千次阅读 2021-04-11 23:58:14
    本文隶属于专栏《100个问题搞定大数据理论体系》,该专栏为笔者原创,引用请注明来源,不足错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构文献引用请见100个问题搞定大数据理论体系 解答 事件时间指的是...
  • 什么事件流?

    万次阅读 2017-07-30 23:43:06
    一、事件流的定义 页面触发一个事件时,会按照一定的顺序来响应事件事件的响应过程为事件流 就我个人理解就是网页对点击事件的排序顺序就是事件流 二、事件流的分类 1、冒泡型的事件流(任何一款...
  • 事件驱动是什么

    千次阅读 2018-11-28 10:17:12
    事件通知 当一个系统发送了事件消息通知其它系统在自身域中做改变时,会发生事件通知。事件通知的一个关键因素是源系统并不真正十分关心响应。通常源系统根本就不希望得到应答,或者如果有一个源系统关心的响应,这...
  • 鼠标事件

    千次阅读 2019-01-21 13:22:14
    这些方法的语义化都很好,大家看名字基本都懂是什么意思。 其中,contextmenu是右键出现菜单事件,并不是右键事件。 click是一个完整的点击事件,包括mousedownmouseup。 mouseovermouseout是一组事件,...
  • 事件传递 ----冒泡捕获 DOM事件标准定义了两种事件流,这两种事件流分别是捕获冒泡。 许多Web技 术一样,在它们成为标准之前,Netscape微软各自不同地实现了它们。Netscape选择实现了捕获事件流,微软则...
  • wpf的事件和C#的事件区别

    千次阅读 2016-12-26 14:04:56
    wpf的事件和C#的事件区别
  • 事件冒泡和事件捕获初始化代码示例初始化效果图事件冒泡和事件捕获addEventListener()注意stopPropagation() 初始化代码示例 我们先初始化一个小dome,以下是代码 <!DOCTYPE html> <html> <head>...
  • jQuery事件触发js手动触发事件

    千次阅读 2017-04-08 16:10:32
    之前在项目中遇到了需要手动触发事件的问题,比如鼠标双击操作,需要在键盘上按Enter键也有鼠标双击产生的效果,在jQuery中我们知道trigger可以在每一个匹配的元素上触发某类事件,比如$("input").trigger("dblclick...
  • IEDOM事件流的区别

    千次阅读 2019-03-13 19:35:37
    什么是“事件流”? 事件流描述的是从页面中接收事件的顺序 事件流的种类: 事件流主要分为三种 事件冒泡流(IE事件流):事件开始时由最具体的元素(文档中嵌套最深的那个节点)接收,然后逐级向上传播到较为不具体...
  • 什么事件驱动

    千次阅读 2018-03-07 23:23:58
    https://wenda.so.com/q/1362989335066081?src=1401.要理解事件驱动程序,就需要与非事件驱动的程序进行比较。实际上,现代的程序大多是事件驱动的,比如多线程的程序,肯定是事件驱动的。早期则存在许多非事件...
  • clicktap事件

    千次阅读 2019-04-03 11:26:53
    clicktap事件的区别 click事件 click事件是pc端的单机事件,但是当这个事件在移动端实现的时候,会出现延迟300ms的现象,所以移动端一般用tap来代替click。 tap事件 tap可以减少click在移动端的延迟,提高了性能。...
  • [C#]委托和事件(详细讲解)

    万次阅读 多人点赞 2014-03-02 00:23:55
    引言 委托 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件...本文中,我将通过两个范例由浅入深地讲述什么是委托、为什么要使用委托、事件的由来、.Net Framework中的委托和事件、委托
  • 抽空学习了下javascriptjquery的事件设计,收获颇大,总结此贴,大家分享。   (一)事件绑定的几种方式 javascript给DOM绑定事件处理函数总的来说有2种方式:在html文档中绑定、在js代码中绑定。...
  • C# 委托(delegate)和事件(event)详解

    万次阅读 多人点赞 2017-10-11 17:26:08
    C# 中的委托和事件 引言 委托 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很...本文中,我将通过两个范例由浅入深地讲述什么是委托、为什么要使用委托、事件的由来、.Net Framework中的
  • 在设定datasourcedisplaymembervaluemember时,以及手动改变combobox索引值时都不触发该事件, 只是在界面选择combobox不同值时触发。 SelectedIndexChanged事件 当 SelectedIndex 属性更改时发生,索引...
  • 事件流也有两种,分别是事件冒泡和事件捕获,现行的主流是事件冒泡。 以上就是通过原生js将每一个div都绑定了一个事件,且通过useCapture这个参数将事件类型设置为true(捕获)或者 false(默认为false,冒泡) 需要...
  • 什么事件监听?

    千次阅读 2018-05-19 10:59:00
    1.DOM 0级事件,普通的事件事件源.事件类型 = 预处理函数,缺点:后者的事件会将前者的事件覆盖掉 2.DOM 2级事件事件监听 <1>语法:addEventListener(参数1,参数2,参数3),参数1:事件类型,这个事件...
  • C#中委托和事件

    千次阅读 多人点赞 2019-09-26 13:36:33
    关于委托和事件分享三个博客内容: 首先说明下: (1)C#中事件事件时属于类的成员,所以要放在类的内部。 (2)委托属于一个定义,是类、接口类似的,通常放在外部。 (因为大多数委托都要被重用) 委托...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 278,509
精华内容 111,403
关键字:

和事件什么意思