Node学习笔记(六)
2014-08-17 08:40
204 查看
如果你习惯于浏览器javascript编程,你可能用过setTimeout和setInterval函数,这些函数允许你在给定的一段时间去执行某个任务,如下边的代码片段,一旦你加载进入这个web页面,一秒后则会向body体中追加“Hello there”字符串。
setInterval通过给定一个时间间隔去重复一个函数的执行,如果你进入这个web页面,每秒将会重复调用回调函数,即每一秒会向body体中追加“Hello there”字符串。
对于这些函数的需求源于取代静态web页面而成为构建应用的平台,这些调度函数能帮助开发者创建周期性的表单验证,远程数据的同步,和各种需要用户界面延迟反映的交互,Node实现了这组函数,在服务器端他们能被用于协助在许多不同的任务,包括高速缓存期满时,连接池清理,会话超时,轮询和其他重复或者延迟执行的操作。
1.用setTimeout延迟执行一个函数
在某个时候,setTimeout函数让你调度任何函数能够被执行一次,如:
正如浏览器中javascript,setTimeout能够接受一个延迟函数作为第一个参数,并且在函数之后的参数是这个函数被执行的时间,这个参数的单位是毫秒。
调用setTimeout函数返回一个timeout执行的对象,这是一个内部对象,该对象除了使用clearTimeout取消调度的执行,不能用于任何操作。
2.用clearTimeout取消一个函数的执行
一旦你获得了一个timeout执行者对象,你能用它通过调用clearTimeout取消调度函数的执行,如:
在这个例子中,timeout将永远不会在控制台上打印”timed out!”,你另外能够在将来的某个时候取消调度的执行。如:
3.调度和取消一个函数的重复执行
setInterval与setTimeout类似,只是setInterval会在每个给定的时间周期连续的调度函数,你可能想用它来定期的触发执行某些类型的清理例程。收集、记录、检索,查询或其他的任何程序,你可能会发现在重复运行的基础上是有用的。
下面的代码段每秒会在控制台输出”tick”, 如:
如果你不想持续无期限的运行这个任务,或者直到它结束,你能通过调用clearInterval函数取消调度。setInterval返回一个调度执行者对象,你能提供它作为clearInterval的第一个参数去解除调度。如:
4.用process.nextTick延迟一个函数的执行,直到下一个Event Loop迭代
有时候浏览器javascript程序能用setTimeout(callback, 0)作为将来的某个时间延迟执行任务的一种方式,0值告诉javascript runtime,它应该尽可能快的在所有待处理的任务执行完后执行回调函数,这个技术有时被用于不需要立即运行的延迟操作,如,开始动画或者用户事件处理后的某些运算。
在Node中,event loop运行正如其名所示,在处理事件队列的一个循环,每次事件循环执行,被叫做tick. 你能调度一个回调函数在下一个事件循环被执行,也就是下一个tick, setTimeout如果被用在javascript runtime中,则它有自己的调度队列,process.nextTick函数被特定在Node的Event Loop. 通过使用process.nextTick(callback)替代setTimeout(callback,
0),在所有事件队列的任务被执行后,回调才会立即运行,需要注意的是,process对象是Node全局的几个对象之一。
5.阻塞事件循环
Node和javascript runtime一般都是单线程事件循环,在每一个循环上,运行时通过调用被关联的回调函数来处理在队列的下一个事件,当该事件完成时,事件循环检索和处理下一个事件,这个模式会一直继续下去,直到队列为空,如果这些回调函数之一分配了很长的执行时间,事件循环就不能处理在此期间发生的事件,这能导致一个缓慢的应用或服务。
使用处理器密集型的功能时处理事件可能导致事件循环变得缓慢,并且事件排队越来越多,甚至可能会阻塞。这有一个阻塞实例,如:
5.避开事件循环阻塞
你能够使用process.nextTick推迟非关键任务的执行到下一个事件循环,释放当前事件循环,执行其他未完成的事件。这有个例子,如果你需要移除一个已创建的临时文件,但是你在响应到客户端以前不需要移除它,你可以像这样做,如:
6.用setTimeout代替setInterval强制序列化
你想用一个函数做某些I/O操作,如,解析一个日志文件,将会周期性的被执行,你能够通过用setInterval,如:
然而,你必须确保这些函数在同一时间都没执行,如果你用setInterval,你就真的不能保证,如果my_async_function需要一毫秒的时间超过了你使用的间隔时间,他们可能会在同一时间运行。
你需要强制间隔时间在my_async_function结束和下一个周期开始前之间,你能像下边这么做,如:
这声明了一个函数被命名为schedule,并且在声明之后立即执行,这个shedule函数调度do_it函数在一秒后被执行,在一秒过后,这个匿名函数就会被触发,调用my_async_function函数,当这个函数完成时,匿名回调将会被执行。调用schedule函数,你将再一次调度do_it函数在以秒后被执行,重复这个周期。
var oneSecond = 1000 * 1; setTimeout(function() { document.write(‘<p>Hello there</p>’); }, oneSecond);
setInterval通过给定一个时间间隔去重复一个函数的执行,如果你进入这个web页面,每秒将会重复调用回调函数,即每一秒会向body体中追加“Hello there”字符串。
var oneSecond = 1000 * 1; setInterval(function() { document.write(‘<p>Hello there</p>’); }, oneSecond);
对于这些函数的需求源于取代静态web页面而成为构建应用的平台,这些调度函数能帮助开发者创建周期性的表单验证,远程数据的同步,和各种需要用户界面延迟反映的交互,Node实现了这组函数,在服务器端他们能被用于协助在许多不同的任务,包括高速缓存期满时,连接池清理,会话超时,轮询和其他重复或者延迟执行的操作。
1.用setTimeout延迟执行一个函数
在某个时候,setTimeout函数让你调度任何函数能够被执行一次,如:
var timeout_ms = 1000 * 2; //2 seconds var timeout = setTimeout(function() { console.log(“time out!”); }, timeout_ms);
正如浏览器中javascript,setTimeout能够接受一个延迟函数作为第一个参数,并且在函数之后的参数是这个函数被执行的时间,这个参数的单位是毫秒。
调用setTimeout函数返回一个timeout执行的对象,这是一个内部对象,该对象除了使用clearTimeout取消调度的执行,不能用于任何操作。
2.用clearTimeout取消一个函数的执行
一旦你获得了一个timeout执行者对象,你能用它通过调用clearTimeout取消调度函数的执行,如:
var timeoutTime = 1000; // one second var timeout = setTimeout(function() { console.log("timed out!"); }, timeoutTime); clearTimeout(timeout);
在这个例子中,timeout将永远不会在控制台上打印”timed out!”,你另外能够在将来的某个时候取消调度的执行。如:
var timeout = setTimeout(function A() { console.log("timed out!"); }, 2000); setTimeout(function B() { clearTimeout(timeout); }, 1000);
3.调度和取消一个函数的重复执行
setInterval与setTimeout类似,只是setInterval会在每个给定的时间周期连续的调度函数,你可能想用它来定期的触发执行某些类型的清理例程。收集、记录、检索,查询或其他的任何程序,你可能会发现在重复运行的基础上是有用的。
下面的代码段每秒会在控制台输出”tick”, 如:
var period = 1000; // 1 second setInterval(function() { console.log("tick"); }, period);
如果你不想持续无期限的运行这个任务,或者直到它结束,你能通过调用clearInterval函数取消调度。setInterval返回一个调度执行者对象,你能提供它作为clearInterval的第一个参数去解除调度。如:
var interval = setInterval(function() { console.log("tick"); }, 1000); // ... clearInterval(interval);
4.用process.nextTick延迟一个函数的执行,直到下一个Event Loop迭代
有时候浏览器javascript程序能用setTimeout(callback, 0)作为将来的某个时间延迟执行任务的一种方式,0值告诉javascript runtime,它应该尽可能快的在所有待处理的任务执行完后执行回调函数,这个技术有时被用于不需要立即运行的延迟操作,如,开始动画或者用户事件处理后的某些运算。
在Node中,event loop运行正如其名所示,在处理事件队列的一个循环,每次事件循环执行,被叫做tick. 你能调度一个回调函数在下一个事件循环被执行,也就是下一个tick, setTimeout如果被用在javascript runtime中,则它有自己的调度队列,process.nextTick函数被特定在Node的Event Loop. 通过使用process.nextTick(callback)替代setTimeout(callback,
0),在所有事件队列的任务被执行后,回调才会立即运行,需要注意的是,process对象是Node全局的几个对象之一。
5.阻塞事件循环
Node和javascript runtime一般都是单线程事件循环,在每一个循环上,运行时通过调用被关联的回调函数来处理在队列的下一个事件,当该事件完成时,事件循环检索和处理下一个事件,这个模式会一直继续下去,直到队列为空,如果这些回调函数之一分配了很长的执行时间,事件循环就不能处理在此期间发生的事件,这能导致一个缓慢的应用或服务。
使用处理器密集型的功能时处理事件可能导致事件循环变得缓慢,并且事件排队越来越多,甚至可能会阻塞。这有一个阻塞实例,如:
process.nextTick(function nextTick1() { var a = 0; while(true) { a ++; } }); process.nextTick(function nextTick2() { console.log("next tick"); }); setTimeout(function timeout() { console.log("timeout"); }, 1000);在这个例子中,nextTick2和timeout函数将永远不会有机会运行,因为在第一个nextTick函数无限的运行,事件循环被阻塞,事件调度timeout函数被期望在一秒后运行,此时,也不会运行了。当用setTimeout,回调函数会进入调度队列,在这个例子中,没有事件被派发,这是一个极限的例子,但是你能看到,运行一个CPU密集型的任务可能阻塞或者延缓你的事件循环。
5.避开事件循环阻塞
你能够使用process.nextTick推迟非关键任务的执行到下一个事件循环,释放当前事件循环,执行其他未完成的事件。这有个例子,如果你需要移除一个已创建的临时文件,但是你在响应到客户端以前不需要移除它,你可以像这样做,如:
stream.on("data", function(data) { stream.end("my response"); process.nextTick(function() { fs.unlink("/path/to/file”); }); });
6.用setTimeout代替setInterval强制序列化
你想用一个函数做某些I/O操作,如,解析一个日志文件,将会周期性的被执行,你能够通过用setInterval,如:
var interval = 1000; setInterval(function() { my_async_function(function() { console.log('my_async_function finished!’); }); },interval);
然而,你必须确保这些函数在同一时间都没执行,如果你用setInterval,你就真的不能保证,如果my_async_function需要一毫秒的时间超过了你使用的间隔时间,他们可能会在同一时间运行。
你需要强制间隔时间在my_async_function结束和下一个周期开始前之间,你能像下边这么做,如:
(function schedule() { setTimeout(function do_it() { my_async_function(function() { console.log('async is done!'); schedule(); }); }, interval); }());
这声明了一个函数被命名为schedule,并且在声明之后立即执行,这个shedule函数调度do_it函数在一秒后被执行,在一秒过后,这个匿名函数就会被触发,调用my_async_function函数,当这个函数完成时,匿名回调将会被执行。调用schedule函数,你将再一次调度do_it函数在以秒后被执行,重复这个周期。
相关文章推荐
- Node.js文档学习笔记(2)
- hadoop学习笔记(2)-hadoop安装目录权限的问题导致datanode启动失败
- pomelo学习笔记 (3) node.js 与 c 客户端 Diffie-Hellman 密钥交换算法的实现
- hadoop学习笔记之start-all.sh 无法启动NameNode,DataNode
- node.js 学习笔记五:连接mongodb
- 云计算学习笔记---异常处理---hadoop问题处理ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: java.lang.NullPoin
- BDA驱动学习笔记(3):NODE例程
- node.js 学习笔记四:读取文件
- NODE.JS学习笔记——CRYPTO 加密模块
- node.js 学习笔记一:创建一个服务器
- Node.js文档学习笔记(1)
- Node.js 学习笔记(一)
- cocos2d学习笔记(六)CCParallaxNode和Tile Map
- node.js 学习笔记二:创建属于自己的模块
- Node.js + mongoose + mongodb 学习笔记
- Node.js学习笔记-STDIO Module
- Node.js入门学习笔记-IDE选择/配置之WebStorm(windows)
- Node.JS学习笔记
- Node.js学习笔记
- 客户端网络pomelo学习笔记 (3) node.js 与 c 客户端 Diffie-Hellman 密钥交换算法的实现客户端网络