我的Node.js学习之路(三)--node.js作用、回调、同步和异步代码 以及事件循环 |
一,node.js的作用, I/O的意义,(I/O是输入/输出的简写,如:键盘敲入文本,输入,屏幕上看到文本显示输出 。鼠标移动,在屏幕上看到鼠标的移动 。终端的输入,和看到的输出 。等等) Js代码 var http = require(http), urls = [www.baidu.com,www.10jqka.com.cn,www.duokan.com]; function fetchPage(url){ var start = new Date(); http.get({host:url},function(res){ console.log("Got response from:" + url); console.log("Request took:",new Date() - start, "ms"); }); } for(var i=0; i<urls.length; i++){ fetchPage(urls[i]); } 命名为,node.js 我们要求node.js访问三个url并报告收到响应的情况以及所耗费的时间 。 1,$("p").hide(slow); 2,$("p").hide(slow,function(){alert("The paragraph is now hidden")}); 回调是可选的, $("p").hide(slow); alert("The paragraph is now hidden");//1 $("p").hide(slow,function(){alert("The paragraph is now hidden")});//2 1,是没有回调,,执行顺序是一样但是,我们可以看到p段落还没有隐藏完全,alert就出来 function haveBreakfast(food,drink,callback){ console.log(Having barakfast of + food + , + drink); if(callback && typeof(callback) === "function"){ callback(); } } haveBreakfast(foast,coffee,function(){ console.log(Finished breakfast. Time to go to work!); }); Having barakfast of foast,coffee Finished breakfast. Time to go to work! 这里是创建了一个函数,有三个参数,第三个参数是callback,这个参数必须是个函数 。 node.js中使用filesystem模块从磁盘上读入文件内容的示例 var fs = require(fs); fs.readFile(somefile.txt,utf8,function(err,data){ if(err) throw err; console.log(data); }); 结果是:somefile.txt里面的内容 。 Js代码 var http = require(http); http.get({host:shapeshed.com},function(res){ console.log("Got response:" + res.statusCode); }).on(error,function(e){ console.log("Got error:" + e.message); }); 结果:Got response:200 Js代码 var fs = require(fs), http = require(http); http.get({host:www.baidu.com},function(res){ console.log("baidu.com"); }).on(error,function(e){ console.log("Got error:" + e.message); }); fs.readFile(somefile.txt,utf8,function(err,data){ if(err) throw err; console.log("somefile"); }); http.get({host:www.duokan.com},function(res){ console.log("duokan.com"); }).on(error,function(e){ console.log("Got error:" + e.message); }); fs.readFile(somefile2.txt,utf8,function(err,data){ if(err) throw err; console.log("somefile2"); }); 我们能知道哪个操作先返回吗?
先看代码,同步(或者阻塞)代码 Js代码 function sleep(milliseconds){ var start = new Date().getTime(); while((new Date().getTime() -start) < milliseconds){ } } function fetchPage(){ console.log(fetching page); sleep(2000); console.log(data returned from requesting page); } function fetchApi(){ console.log(fetching api); sleep(2000); console.log(data returned from the api); } fetchPage(); fetchApi(); Js代码 var http = require(http); function fetchPage(){ console.log(fetching page); http.get({host:www.baidu.com,path:/?delay=2000}, function(res){ console.log(data returned from requesting page); }).on(error,function(e){ console.log("There was an error" + e); }); } function fetchApi(){ console.log(fetching api); http.get({host:www.baidu.com,path:/?delay=2000}, function(res){ console.log(data returned from requesting api); }).on(error,function(e){ console.log("There was an error" + e); }); } fetchPage(); fetchApi(); 允许这段代码的时候,就不再等待fetchPage()函数返回了,fetchApi()函数随之立刻被调用 。代码通过使用回调,是非阻塞的了 。一旦调用了,两个函数都会侦听远程服务器的返回,并以此触发回调函数 。 Node.js使用javascript的事件循环来支持它所推崇的异步编程风格 。基本上,事件循环使得系统可以将回调函数先保存起来,而后当事件在将来发生时再运行 。这可以是数据库返回数据,也可以是HTTP请求返回数据 。因为回调函数的执行被推迟到事件反生之后,于是就无需停止执行,控制流可以返回到Node运行时的环境,从而让其他事情发生 。 Node.js经常被当作是一个网络编程框架,因为它的设计旨在处理网络中数据流的不确定性 。促成这样的设计的是事件循环和对回调的使用,他们似的程序员可以编写对网络或I/O事件进行响应的异步代码 。 需要遵循的规则有:函数必须快速返回,函数不得阻塞,长时间运行的操作必须移到另一个进程中 。 |