最新消息:从今天开始,做一个有好习惯的人。

nodeJs非阻塞的实现

其他 迷路的老鼠 1860浏览 0评论

nodeJs官方的说法是:在nodeJs中除了代码,所有一切都是并行的。也就是说可以在不新增进程的情况下,依然可以对任务进行并行处理。

实现的方式就是通过事件轮询,当然这也不是个简单的事情,要使用事件轮询就需要使用回调,将函数作为参数传递给其他需要花时间做处理的函数(比如复杂逻辑)。

简单的一句话就是:nodeJs非阻塞是通过轮询回调事件实现的。

处理复杂逻辑时,如果不做处理,会阻塞掉进程,导致其他请求不能执行(nodeJs时单进程),所以对这类逻辑用异步处理,都是请求时同步执行的,异步的结果无法返回给用户,就必须采用异步回调的方式,子进程执行完成后回调传入的回调函数,确保结果正常返回,同时避免进程阻塞。

先来看一个错误的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var exec = require("child_process").exec;

function start() {

console.log("Request handler 'start' was called.");

var content = "empty";

exec("find /", function (error, stdout, stderr) {

content = stdout;

});

return content;
}

function upload() {

console.log("Request handler 'upload' was called.");

return "Hello Upload";

}

exports.start = start;

exports.upload = upload;

“find /”是非常耗时的,我们这里通过exec()开启一个子进程去执行,但是return content是同步执行的,返回值会是”empty”。这时需要对这个子进程写入回调,让子进程执行完后回调返回结果。

代码修改一下:

server.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var http = require("http");

var url = require("url");

function start(route, handle) {

function onRequest(request, response) {

var pathname = url.parse(request.url).pathname;

console.log("Request for " + pathname + " received.");

route(handle, pathname, response);

}

http.createServer(onRequest).listen(8888);

console.log("Server has started.");

}

exports.start = start;

router.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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;

requestHandler.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var exec = require("child_process").exec;

function start(response) {

console.log("Request handler 'start' was called.");

exec("find /", function (error, stdout, stderr) {

response.writeHead(200, {"Content-Type": "text/plain"});

response.write(stdout); response.end(); });

}

function upload(response) {

console.log("Request handler 'upload' was called.");

response.writeHead(200, {"Content-Type": "text/plain"});

response.write("Hello Upload");

response.end();

}
exports.start = start;

exports.upload = upload;

这里把response作为回调函数,确保子进程执行完后回调返回数据。

f0bbbca1c04b7009d93bc6f41e30eec2

转载请注明:迷路的老鼠 » nodeJs非阻塞的实现

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址