nodejs异步任务,nodejs定时任务

  nodejs异步任务,nodejs定时任务

  Nodejs异步定时器滴答;第节-代码

  Nodejs异步定时器滴答;计时器:

  在前端开发中,我们经常使用setTimeout函数组。这组函数实际上不属于语言标准,它们只是扩展。在浏览器中,它们属于BOM(浏览器对象扩展),即它的确切定义是:window.setTimeout,与window.alert、window . open . http://code.google.com/p/doctype/wiki/WindowSetTimeoutMethod等函数处于同一级别

  你可以在浏览器的控制台中监控窗口对象,或者检查chromium的实现:

  http://codesearch . Google . com/# OAMlx _ jo-CK/src/third _ party/WebKit/Source/WebCore/page/DOM window . h

  当然,在nodejs中,您必须实现自己的计时器。nodejs的src目录中,timer.h/cc是libev中ev_timer的浅包。在src/node.js文件中,这组函数放在全局范围内(相当于浏览器中的窗口)。startup . global time outs=function(){

  global.setTimeout=function() {

  var t=native module . require( timers );

  return t.setTimeout.apply(this,arguments);

  global.setInterval=function() {

  var t=native module . require( timers );

  return t.setInterval.apply(this,arguments);

  .

  通过我们对libev的分析,已经知道libev中队timer的添加/删除/更新操作都是O(lg(n)),

  (http://cnodejs.org/blog/?的利比夫分析p=2489)

  但实际上,在我们的日常开发中,以网络套接字为例,我们经常会为它设置超时,即如果这个套接字在一段时间内(120秒或60秒)没有活动事件,我们就会关闭它(这个技巧很重要,否则由于一些内部或外部的原因,很容易占用过多的描述符)。注意,我们的超时是一个统一的值。这时,我们可以采用下面的算法。

  当我们在不同的时间多次调用setTimeout(fn,1000)时,我们只通过一个定时器来管理所有这些事件。这些事件放在一个双链表中,顺序自然是按时间排序的。当定时器在某个时间被触发时,它将依次从prev链表头中取出节点并检查它们。如果超时,就会被触发。

  (见lib/timer _legacy.js由于libev在windows上不能很好的工作,nodejs项目组为libev和libeio做了一层封装,叫做libuv。使用传统方法的文件以_ legacy结尾,使用libuv的文件以_uv结尾,如net _ legacy.js、net _ uv.js、timers _ legacy。

  当我们需要改变一个异步事件的时候,比如我们添加了超时控制的socket上发生了一个读/写事件,这个时候我们需要重置定时器,我们只需要把这个事件从链表中转移到链表的末尾。

  (参见lib/net_legacy.js)

  删除的时候情况也差不多,所以在这个场景中,只消耗了一个ev_timer,我们所有的异步事件都是以O(1)复杂度添加/删除/更新的。

  注意在lib/timer_*中。js,超时值=0时不进行优化,

  exports . exports . settimeout=function(callback,after) {

  if (after=0) {

  after==0时使用小写

  timer=新计时器();

  timer.ontimeout=回调;

  否则{

  }

  同时,setInterval函数也没有优化。

  下一个刻度:

  NextTick是个很有意思的东西。它实际上是由准备观察器实现的。libev中事件循环的每次迭代在nodejs中称为“Tick”,而在libev中支持prepare watcher,每次迭代开始时触发。在src/node.cc中,我们看到类似的代码(以4.9版为例):

  ev _ prepare _ init(node:prepare _ tick _ watcher,node:prepare tick);

  EV _ prepare _ start(EV _ DEFAULT _ UC _ node:prepare _ tick _ watcher);

  EV _ unref(EV _ DEFAULT _ UC);

  函数PrepareTick中会调用一个回调函数,这个function _tickCallback在src/node.js中:

  startup . process nexttick=function(){

  var next tick queue=[];

  过程。_tickCallback=function() {

  process.nextTick=函数(回调){

  nextTickQueue.push(回调);

  过程。_ needTickCallback();

  };

  当我们调用API process.nextTick时,我们实际上是在nextTickQueue的闭包队列中添加了一个函数。下一个事件循环开始时,会自动触发prepare_tick_watcher,调用我们设置的函数。

  注意上面有一个问题,就是如果没有下一个事件循环的机会,比如此时没有实质性的watcher要监控,那么事件循环就会退出。要避免这种情况,请处理。_needTickCallback()将在nextTick函数中调用一次,这将使tick_spinner(一个空闲的观察器)处于活动状态,以防止退出事件循环。

  从nextTick原理我们知道,当我们添加一个挂起事件时,它的复杂度是O(1),但是如果你使用setTimeout(fn,0),就像我们在libev分析中说的,它的输入输出是O(lg(n)),所以nodejs的官方文档说:

  在围绕事件循环的下一个循环中调用这个回调。这不是setTimeout(fn,0)的简单别名,要高效得多。

  NextTick确实效率高很多,我骗你!

  部分:

  通过以上分析,我们至少可以得出两个肤浅的结论:

  #1如果可能,在调用setTimeout时尝试使用相同的超时值。

  #2尝试使用process.nextTick而不是setTimeout(fn,0)

  标签:

  原创文章

  由windyrobin于2011年9月13日21: 45发表

  由windyrobin在2012年1月19日11: 55重新编辑

  分享到微博

  回复2 #1

  爱管闲事的

  最后,总结有很多好处。希望爱多哥能有更多简单的文章~

  持续关注~

  史努比在2011年9月14日22: 15回复。

  #2

  宿迁

  定时器多路复用。消除疑虑。以后还得深入源代码。

  宿迁回复2011年9月23日00: 21。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • Vue项目启动,nodejs启动vue项目,如何启动一个Vue.js项目
  • pm2自动重启node项目,nodejs 部署,nodejs高大上的部署方式(PM2)
  • pm2管理nodejs,
  • npm切换淘宝镜像指令,node配置淘宝镜像
  • node实现爬虫的几种简易方式选择,node实现爬虫的几种简易方式选择,node实现爬虫的几种简易方式
  • node写爬虫,node实现爬虫的几种简易方式选择
  • nodemon怎么安装,nodemon app.js
  • nodemon怎么安装,nodemon app.js,node.js开发辅助工具nodemon安装与配置详解
  • nodejs __dirname,node环境变量
  • nodejs __dirname,node环境变量,node全局变量__dirname与__filename的区别
  • node.js配置环境变量,如何配置node环境
  • node.js配置环境变量,如何配置node环境,node安装及环境变量配置详细教程
  • node. js安装,Windows安装node
  • node. js安装,Windows安装node,Node.js安装详细步骤教程(Windows版)详解
  • node sass安装不上,安装sass一定安装nodesass吗
  • 留言与评论(共有 条评论)
       
    验证码: