• 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);
  • 相关阅读:
    #Hadoop集群部署
    #Linux Keepalived 负载均衡
    #Linux LVS 负载均衡
    #Kafka 彻底删除topic
    #Linux Keepalived 双机热备
    Python #图片验证码
    Linux #tar
    MongoDB #$set的问题
    Django #CSRF
    keystone环境搭建(源码方式+yum方式)(ocata版本)
  • 原文地址:https://www.cnblogs.com/loaderman/p/11498559.html
Copyright © 2020-2023  润新知