makeing node lsls的音标

NodeJs中的非阻塞方法 - rainsilence - ITeye技术网站
博客分类:
首先我们利用NodeJs先构建一个基本的服务器。
var requestHandler = require("./requestHandler");
var server = require("./server");
var route = {
"/hello": requestHandler.hello,
"/upload": requestHandler.upload
server.start(route);
var http = require("http");
var url = require("url");
exports.start = function(route) {
var server = http.createServer(function(req, res) {
var pathName = url.parse(req.url).
var handler = route[pathName];
if (handler) {
console.log("Through path:" + pathName + ":" + new Date().getTime());
handler(res);
res.writeHead(404, {"Content-Type": "text/plain"});
res.end();
server.listen(8088);
requestHandler.js
exports.hello = function(res) {
res.writeHead(200, {"Content-Type": "text/plain"});
res.write("say hello.");
res.end();
exports.upload = function(res) {
res.writeHead(200, {"Content-Type": "text/plain"});
res.write("upload");
res.end();
在cmd中,键入node index.js即可启动。
但是,上面的代码是阻塞的。如果在createServer的回调函数中,有花费长时间的计算。那么会阻塞node.js的事件轮询。
NodeJS中,他的高效,关键在于快速的返回事件循环。
我们将requestHandler.js改造如下,在这个例子中,由于事件循环一直被sleep函数阻塞着,导致createServer的callback无法及时返回。
function sleep(milliSecond) {
var startTime = new Date().getTime();
console.log(startTime);
while(new Date().getTime() &= milliSecond + startTime) {
console.log(new Date().getTime());
exports.hello = function(res) {
sleep(20000);
res.writeHead(200, {"Content-Type": "text/plain"});
res.write("say hello.");
res.end();
exports.upload = function(res) {
res.writeHead(200, {"Content-Type": "text/plain"});
res.write("upload");
res.end();
那么先键入http://localhost:8088/hello,后键入http://localhost:8088/upload。你会发现,upload虽然不需要花费太多时间,但是却要等到hello完成。
我们试图找寻异步调用的方法。比如formidable中的上传,经测试是非阻塞的。查看formidable的源码,发现最关键的是下面的代码:
IncomingForm.prototype.parse = function(req, cb) {
this.pause = function() {
req.pause();
} catch (err) {
// the stream was destroyed
if (!this.ended) {
// before it was completed, crash & burn
this._error(err);
this.resume = function() {
req.resume();
} catch (err) {
// the stream was destroyed
if (!this.ended) {
// before it was completed, crash & burn
this._error(err);
this.writeHeaders(req.headers);
var self =
.on('error', function(err) {
self._error(err);
.on('aborted', function() {
self.emit('aborted');
.on('data', function(buffer) {
self.write(buffer);
.on('end', function() {
if (self.error) {
var err = self._parser.end();
if (err) {
self._error(err);
var fields = {}, files = {};
.on('field', function(name, value) {
fields[name] =
.on('file', function(name, file) {
files[name] =
.on('error', function(err) {
cb(err, fields, files);
.on('end', function() {
cb(null, fields, files);
在parse中,将head信息解析出来这段是阻塞的。但是真正上传文件却是在req.on(data)中,是利用了事件驱动,是非阻塞的。也就是说,他的非阻塞模型依赖整个nodeJS事件分派架构。
那么像sleep那样消耗大量计算,但是又不能依赖nodeJS分派架构的时候怎么办?
现在介绍一种,类似于html5 WebWorker的方法。
将requestHandler.js改造如下:
var childProcess = require("child_process");
exports.hello = function(res) {
var n = childProcess.fork(__dirname + "/subProcess.js");
n.on('message', function() {
res.writeHead(200, {"Content-Type": "text/plain"});
res.write("say hello.");
res.end();
n.send({});
exports.upload = function(res) {
res.writeHead(200, {"Content-Type": "text/plain"});
res.write("upload");
res.end();
并加入subProcess.js
function sleep(milliSecond) {
var startTime = new Date().getTime();
console.log(startTime);
while(new Date().getTime() &= milliSecond + startTime) {
console.log(new Date().getTime());
process.on('message', function() {
sleep(20000);
process.send({});
测试,当hello还在等待时,upload已经返回。
yaolifei 写道你好,请教几个问题:createServer的callback是阻塞的吗? 我以为每个请求的调用都不影响,不知道究竟是怎么样的过程。还有一个问题,看你的代码应该是看了nodejs入门,我也看了,你那个hello里面的sleep导致upload也阻塞了可以说createServer是阻塞的。但是如果这样写:function start(response) {
console.log("Request handler 'start' was called.");
exec("ls -lah", function (error, stdout, stderr) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write(stdout);
response.end();
}exec这个应该是非阻塞的吧?那为什么我这样写:function start(response) {
console.log("Request handler 'start' was called.");
exec('dir', function(error, stdout, stderr){
function sleep(milliSeconds){
var startTime = new Date().getTime();
while (new Date().getTime() & startTime + milliSeconds);
sleep(10000);
response.writeHead(200, {'Content-Type': 'text/plain'});
response.write(stdout);
response.end();
}我把sleep放在非阻塞的方法里执行,应该也不会阻塞upload吧,但是还是会阻塞话说要把sleep放在subProcess.js中的process.on('message', function() {& &&& sleep(20000);& &&& process.send({});& });这样才不会阻塞,我试了一晚上才发现的说...html5 WebWorker也是一样的原理
你好,请教几个问题:createServer的callback是阻塞的吗? 我以为每个请求的调用都不影响,不知道究竟是怎么样的过程。还有一个问题,看你的代码应该是看了nodejs入门,我也看了,你那个hello里面的sleep导致upload也阻塞了可以说createServer是阻塞的。但是如果这样写:function start(response) {
console.log("Request handler 'start' was called.");
exec("ls -lah", function (error, stdout, stderr) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write(stdout);
response.end();
}exec这个应该是非阻塞的吧?那为什么我这样写:function start(response) {
console.log("Request handler 'start' was called.");
exec('dir', function(error, stdout, stderr){
function sleep(milliSeconds){
var startTime = new Date().getTime();
while (new Date().getTime() & startTime + milliSeconds);
sleep(10000);
response.writeHead(200, {'Content-Type': 'text/plain'});
response.write(stdout);
response.end();
}我把sleep放在非阻塞的方法里执行,应该也不会阻塞upload吧,但是还是会阻塞话说要把sleep放在subProcess.js中的process.on('message', function() {& &&& sleep(20000);& &&& process.send({});& });这样才不会阻塞,我试了一晚上才发现的说...
rainsilence
浏览: 114970 次
来自: 上海
promise/A为什么能写的这么多出来
if (db.version != &1 ...
glchen 写道yaolifei 写道你好,请教几个问题:c ...
yaolifei 写道你好,请教几个问题:createServ ...

我要回帖

更多关于 node 的文章

 

随机推荐