跟着Node入门学习nodeJS,小笔记
Node.JS???
Node.js 使用Google的V8虚拟机,使javaScript代码能在脱离浏览器环境的情况下运行,相当于说Node.js提供了一个可以解释并执行JS代码的环境。
Node.js 的核心是模块化,Node.js通过代码模块化简化很多重复的操作,相当于提供了一个功能强大的库
Web过程
-
index.js
作为入口,引导和启动其他模块,var server = require("./server"); var router = require("./router"); var requestHandlers = require("./requestHandlers"); var handle = {}; handle['/'] = requestHandlers.start; handle['/start'] = requestHandlers.start; handle['/upload'] = requestHandlers.upload; server.start(router.route,handle); //调用server模块提供的接口
-
server.js
使用http模块创建服务器监听端口,使用url模块解析请求,调用router模块var http = require("http"); var url = require("url"); function start(route, handle) { function onRequest(request, response) { var pathname = url.parse(request.url).pathname; route(handle, pathname,response); .... } http.createServer(onRequest).listen(8888); console.log("Server has started."); } exports.start = start; //提供start方法接口
-
router.js
按请求值(如 /start || /upload)调用请求处理程序function route(handle, pathname, response) { console.log("About to route a request for " + pathname); if (typeof handle[pathname] === 'function') { handle[pathname](response); } else { console.log("No request handler found for " + pathname); response.writeHead(404, {"Content-Type": "text/plain"}); response.write("404 Not found"); response.end(); } } exports.route = route; //提供接口
-
requestHandlers.js
各种处理方法,对请求作出响应,让请求处理程序可以和浏览器进行“对话”。function start(){} function upload(){} exports.start = start; exports.upload = upload; //方法接口
要注意的问题
Q1.异步与同步,阻塞与非阻塞
-
异步与同步
同步:发起处理后要在原地等待结果,取到结果后再进行下一步操作由调用者主动等待这个调用的结果
异步:发起处理后可以去做其他事,结果出来后再去取结果
被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用
知乎上看到的栗子
你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”我查一下",然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。
而异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。 -
阻塞和非阻塞
阻塞指在结果返回前,线程被挂起
非阻塞指线程不会被一个调用独占还是知乎上的栗子
你打电话问书店老板有没有《分布式系统》这本书,你如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果,如果是非阻塞式调用,你不管老板有没有告诉你,你自己先一边去玩了, 当然你也要偶尔过几分钟check一下老板有没有返回结果。
在这里阻塞与非阻塞与是否同步异步无关。跟老板通过什么方式回答你结果无关。NodeJS 并行机制
Node.js是单线程的。它通过事件轮询(event loop)来实现并行操作,因此在使用Node.js时尽量使用非阻塞操作,通常的实现方法为使用回调函数
Q2.如何响应
1. 在请求处理程序中通过return返回值,在HTTP服务器统一封装为response
在上一问中可知要尽量避免阻塞方式,那么在使用return时就会遇到问题
var exec = require("child_process").exec;
//调用child_process模块的exec方法,功能从Node.js来执行一个shell命令
function start() {
console.log("Request handler 'start' was called.");
var content = "empty";
exec("ls -lah", function (error, stdout, stderr) {
content = stdout;
});
/* exec使node.js执行ls -lah命令,
为了实现非阻塞,使用回调函数把结果赋值给content变量*/
return content;
}
function upload() {
console.log("Request handler 'upload' was called.");
return "Hello Upload";
}
exports.start = start;
exports.upload = upload;
得到的结果为"empty"
原因分析:调用exec()后,就执行了return content,但此时因exec()的执行是异步的(nodejs异步处理)回调函数还没有执行到,于是return 回来的是empty
2.不限定响应的内容要在HTTP服务器封装,通过函数传值将response对象直接传递至需要的模块处理
Q3.POST
为处理过大的数据,使用非阻塞方式,将数据分成小数据块,然后通过触发特定的事件,将这些小数据块传递给回调函数(data小数据块到达,end数据接收完毕)
对request进行监听,监听data事件和end事件。
request.setEncoding("utf8");
request.addListener("data", function(postDataChunk) {
postData += postDataChunk;
console.log("Received POST data chunk '"+
postDataChunk + "'.");
});
request.addListener("end", function() {
route(handle, pathname, response, postData);
});
处理postData数据querystring.parse(postData).text);
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。