Nodejs 的非阻塞 I/O、 异步、 事件驱动

Nodejs 的单线程 非阻塞 I/O 事件驱动
JavaPHP 或者.net 等服务器端语言中,会为每一个客户端连接创建一个新的线程。
而每个线程需要耗费大约 2MB 内存。也就是说,理论上,一个 8GB 内存的服务器可以同时
连接的最大用户数为 4000 个左右。要让 Web 应用程序支持更多的用户,就需要增加服务器
的数量,而 Web 应用程序的硬件成本当然就上升了。
Node.js 不为每个客户连接创建一个新的线程, 而仅仅使用一个线程。当有用户连接了,
就触发一个内部事件,通过非阻塞 I/O、事件驱动机制,让 Node.js 程序宏观上也是并行的。
使用 Node.js,一个 8GB 内存的服务器,可以同时处理超过 4 万用户的连接

Nodejs 回调处理异步

//错误的写法:
function getData(){
//模拟请求数据
var result='';
setTimeout
(function(){
  result='这是请求到的数据'
},200);
return result;
}
console.log(getData());/*异步导致请求不到数据*/
//正确的处理异步:
function getData(callback){
//模拟请求数据
var result='';
setTimeout
(function(){
  result='这是请求到的数据';
  callback(result);
},200);
}
getData(function(data){
  console.log(data);
})

Nodejs events 模块处理异步

Node.js 有多个内置的事件,我们可以通过引入 events 模块,并通过实例化 EventEmitter类来绑定和监听事件。

// 引入 events 模块
var events = require('events');
var EventEmitter=new events.EventEmitter(); /*实例化事件对象*/
EventEmitter.on('toparent',function(){
    console.log('接收到了广播事件');
})
setTimeout
(function(){
    console.log('广播');
    EventEmitter.emit('toparent'); /*发送广播*/
 },1000)

案例:

getmimefromfile.js

exports.getMime=function(fs,extname,callback){  /*获取后缀名的方法*/

    fs.readFile('./mime.json',function(err,data){

        if(err){
            console.log('mime.json文件不存在');
            return false;
        }
        //console.log(data.toString());

        var Mimes=JSON.parse(data.toString());

        var result= Mimes[extname] || 'text/html';

        callback(result)

    })


}

getmimefromfile_events.js

exports.getMime=function(fs,EventEmitter,extname){  /*获取后缀名的方法*/

    fs.readFile('./mime.json',function(err,data){

        if(err){
            console.log('mime.json文件不存在');
            return false;
        }
        //console.log(data.toString());

        var Mimes=JSON.parse(data.toString());

        var result= Mimes[extname] || 'text/html';

        EventEmitter.emit('to_mime',result);

    })
}

one.js:

//引入http模块
var http=require('http');
//fs模块
var fs=require('fs');
//path模块
var path=require('path');  /*nodejs自带的模块*/
//url模块
var url=require('url');
//引入扩展名的方法是在文件里面获取到的。
var mimeModel=require('./model/getmimefromfile.js');
//console.log(mimeModel.getMime('.css'));   //获取文件类型
http.createServer(function(req,res){
    //http://localhost:8001/news.html    /news.html
    //http://localhost:8001/index.html    /index.html
    //css/dmb.bottom.css
    //xxx.json?214214124
    var pathname=url.parse(req.url).pathname;
    console.log(pathname);
    if(pathname=='/'){
        pathname='/index.html'; /*默认加载的首页*/
    }
    //获取文件的后缀名
    var extname=path.extname(pathname);
    if(pathname!='/favicon.ico'){  /*过滤请求favicon.ico*/
        //console.log(pathname);
        //文件操作获取 static下面的index.html

        fs.readFile('static/'+pathname,function(err,data){

            if(err){  /*么有这个文件*/

                console.log('404');

                fs.readFile('static/404.html',function(error,data404){
                    if(error){
                        console.log(error);
                    }
                    res.writeHead(404,{"Content-Type":"text/html;charset='utf-8'"});
                    res.write(data404);
                    res.end(); /*结束响应*/
                })

            }else{ /*返回这个文件*/

                var mime=mimeModel.getMime(fs,extname,function(mime){
                    res.writeHead(200,{"Content-Type":""+mime+";charset='utf-8'"});
                    res.write(data);
                    res.end(); /*结束响应*/
                });

            }
        })

    }

}).listen(8002);

two.js

//引入http模块
var http=require('http');
//fs模块
var fs=require('fs');
//path模块
var path=require('path');  /*nodejs自带的模块*/
//url模块
var url=require('url');
var events=require('events');
var EventEmitter=new events.EventEmitter();
var mimeModel=require('./model/getmimefromfile_events.js');
//引入扩展名的方法是在文件里面获取到的。
//console.log(mimeModel.getMime('.css'));   //获取文件类型

http.createServer(function(req,res){
    //http://localhost:8001/news.html    /news.html
    //http://localhost:8001/index.html    /index.html
    //css/dmb.bottom.css
    //xxx.json?214214124
    var pathname=url.parse(req.url).pathname;
    console.log(pathname);
    if(pathname=='/'){
        pathname='/index.html'; /*默认加载的首页*/
    }
    //获取文件的后缀名
    var extname=path.extname(pathname);
    if(pathname!='/favicon.ico'){  /*过滤请求favicon.ico*/
        //console.log(pathname);
        //文件操作获取 static下面的index.html
        fs.readFile('static/'+pathname,function(err,data){
            if(err){  /*么有这个文件*/
               console.log('404');
                fs.readFile('static/404.html',function(error,data404){
                    if(error){
                        console.log(error);
                    }
                    res.writeHead(404,{"Content-Type":"text/html;charset='utf-8'"});
                    res.write(data404);
                    res.end(); /*结束响应*/
                })
            }else{ /*返回这个文件*/
                mimeModel.getMime(fs,EventEmitter,extname);  /*调用获取数据的方法*/
                EventEmitter.on('to_mime',function(mime){
                    res.writeHead(200,{"Content-Type":""+mime+";charset='utf-8'"});
                    //res.write(data);
                    res.end(data); /*结束响应*/
                })
            }
        })
    }

}).listen(8002);
原文地址:https://www.cnblogs.com/loaderman/p/11498559.html