阻塞?非阻塞?
到目前为止,我们的路由模块工作一切正常,但实际上在处理阻塞讲求时就会出现问题。
我们自底向上的稍微修改一下各个模块
第一个是 requesthandler.js, 在路由b的时候增加一个 睡眠 5秒
到目前为止,我们的路由模块工作一切正常,但实际上在处理阻塞讲求时就会出现问题。
我们自底向上的稍微修改一下各个模块
第一个是 requesthandler.js, 在路由b的时候增加一个 睡眠 5秒
function a(){
console.log("welcome to visit a :) ");
return "This is A!"
}
function b(){
sleep(5000);
return "Hello B";
}
function sleep(t){
var now = new Date();
var d = now.getTime();
var e = d + t;
while(new Date().getTime() < e);
}
exports.a = a;
exports.b = b;
第二个是 routes.js 把requestHandler返回的内容,返回给上面
function get(pathname , config){
console.log("routes to :"+pathname);
if (typeof(config[pathname]) === 'function') {
return config[pathname]();
} else{
console.log("routes to empty path: " + pathname);
}
};
exports.get = get;
第三个是 server.js ,把路由返回的内容,显示到网页中去
function start(get, config){
var http = require("http");
var url = require("url");
var querystring = require("querystring");
var server = http.createServer(function(request, response){
response.writeHead(200, {"Content-Type":"text/plain"});
var url_obj = url.parse(request.url);
response.write("\n pathname:"+url_obj.pathname);
response.write("\n query:"+url_obj.query);
var content = get(url_obj.pathname, config);
response.write("\n"+content);
var qs = querystring.parse(url_obj.query);
response.write("\n a:"+qs["a"]);
response.write("\n b:"+qs.b);
response.write("\n c:"+qs.c);
response.end();
});
server.listen(8888);
}
exports.start = start;
好了,接下来运行 node index
打开一两个浏览器窗口,
第一个输入 http://localhost:8888/a 但不要回车访问
第二个输入 http://localhost:8888/b 回车访问
迅速切到第一个窗口,回车访问 /a
你会发现 /a 迟迟没有返回东西,直到/b 窗口的Hello B 返回, /a的This is a 才返回
两个疑问涌上心头
1.可是我在/a里没有任何耗时的操作啊, 这是为什么??
2.nodejs 标榜 在node中除了代码,所有的一切都是并行执行的
我们先来解释2, 再来解决1.
2的意思是, node.js 可以在不新增额外纯种的情况下,依然可以对任务 进行并行处理---node.js是单纯种的,它通过事件轮询来实现并行操作,所以我们应该避免阻塞操作,取而代之,使用非阻塞操作。
解决1, 首先我们先来介绍一种错误的,非阻塞方式
首先修改 requestHandler.js
var exec = require("child_process").exec;
function b(){
var content = "empty";
exec("ls -al", function(error, stdout, stderr){
content = stdout;
});
return content;
}
然后重启浏览器,访问 http://localhost:8888/b
很快就能在页面中看到如下返回:
pathname:/b
query:null
empty
a:undefined
b:undefined
c:undefined
你大概已经猜,新引入的模块 child_process.exec()在非阻塞操作中发挥了神奇的作用。
有了他,我们可以执行非常耗时的操作而无需迫使我们的应用 停下来等待该费时操作
(如果想证明,可以将ls -alh 换成find / 这样更耗时的操作来展示效果)
好了,不阻塞已经实现,不过我们显示是想在浏览器中展示出ls 的结果,不是么?
那么正确的方法是什么呢?
请听下回分解!
本课代码下载:
很快就能在页面中看到如下返回:
pathname:/b
query:null
empty
a:undefined
b:undefined
c:undefined
你大概已经猜,新引入的模块 child_process.exec()在非阻塞操作中发挥了神奇的作用。
有了他,我们可以执行非常耗时的操作而无需迫使我们的应用 停下来等待该费时操作
(如果想证明,可以将ls -alh 换成find / 这样更耗时的操作来展示效果)
好了,不阻塞已经实现,不过我们显示是想在浏览器中展示出ls 的结果,不是么?
那么正确的方法是什么呢?
请听下回分解!
本课代码下载:
lesson-08.zip |