zoukankan      html  css  js  c++  java
  • node.js

    1.node是什么?

      Node 是一个让 JavaScript 运行在服务端的开发平台, 发布于2009年5月,由Ryan Dahl开发,实质是对Chrome V8引擎进行了封装。Node对一些特殊用例进行优化,提供替代的API,使得V8在非浏览器环境下运行得更好。 Node用于方便地搭建响应速度快、易于扩展的网络应用。Node 使用事件驱动, 非阻塞I/O 模型而得以轻量和高效,非常适合在分布式设备上运行数据密集型的实时应用。

     1) 什么是 V8?

      V8 JavaScript 引擎是 Google 用于其 Chrome 浏览器的底层 JavaScript 引擎。实际上,JavaScript 引擎负责解释并执行代码。Google 使用 V8 创建了一个用 C++ 编写的超快解释器,该解释器拥有另一个独特特征;您可以下载该引擎并将其嵌入任何应用程序。V8 JavaScript 引擎并不仅限于在一个浏览器中运行。因此,Node 实际上会使用 Google 编写的 V8 JavaScript 引擎,并将其重建为可在服务器上使用。

     2) 什么是i/o?
      i/o ( input,output)  就是服务器的一个读写操作比方说声音输入,听歌,网上传递的字符串

     3) 什么是并发?
      一段时间内有多个程序在运行到运行完毕之间

     4) 什么是进程?
      一个软件运行过程中至少要有一个进程对应

     5) 什么是线程?

      线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务
      多线程与单线程的效率问题:线程本身由于创建和切换的开销,采用多线程不会提高程序的执行速度,反而会降低速度,但是对于频繁IO操作的程序,多线程可以有效的并发.

     6) 同步和异步有什么区别?  

      同步会阻塞: 循环 script加载src
      异步不会阻塞代码:  定时器,link加载css,img加载src.

     7) 什么是异步的IO.  

      要有数据的交互 异步的IO 读文件
      没有数据的交互 异步的非IO setTimeout setInterval

    2.node的解析:
      对象分为两类:
        1) 宿主对象:比如 window history
        2) 内置对象:比如math date regexp array string 
       因为是直接用v8引擎去解析,宿主对象不能解析,没有window对象,此时在node.js中用global表示全局变量,等同于var a.
     
    3.常用方法:
     
      1) 断言
    var flag = 123;    //假定条件
    // 此处省略一万行
    
    // 不能确定flag的值是否还为123,断言判断
    console.assert(flag == 1234,'flag的值根本不等于123');
     
      2) 计算时间
    console.time('test');
    for(var i = 0;i < 100000000;i++){
    }
    console.timeEnd('test');

      

      3) 路径

    console.log(__dirname);   //当前文件所在的路径
    console.log(__filename);   //当前文件的全部路径

     

    4.node.js中的内置模块

      在node中,有一些内置的模块(包),通过require函数引入 

     内置模块:

    1. fs 文件系统;
    2. http 创建服务;
    3. path 路径;
    4. querystring 参数模块;
    5. url 地址栏;
    6. 自定义模块;
    1.fs文件系统的模块:
      1)
    读取文件
    // fs 文件系统的模块
    var fs = require("fs");  
    // console.log(fs);
    
    // 异步读取文件
    fs.readFile('./08.txt','utf8',function(err,data){   //如果编码格式不写,输出的就是一串buffer码
        // console.log(err);   //这是错误,但是没有抛出
        if(err){
            throw err;   //把错误抛出来,有错误可以阻止代码继续往后面走
        }
        console.log(data)
    
    })
    
    // 同步
    // var data = fs.readFileSync("./08.txt",'utf8')   //同步读完就是函数的返回值
    // console.log(data);

     

      2)判断文件是否存在

     //判断文件是否存在
    fs.access('./08.txt',function(err){  
        if(err){
            throw err;
        }
        // 如果没有抛出错误,文件存在
        fs.readFile('./08.txt','utf8',function(err,data){
            if(err) throw err;
    
            console.log(data);
        })
    })
    
    
    fs.access("./abc",function(err){    //可以判断文件夹
        if(err){
            throw err;
        }
        console.log('hello')
    })

       

      3)写文件

    异步写文件
    var obj = {
        "uname" : "admin",
        "upassword" : "admin" 
    }
    var arr = [];
    // su shu 
    arr.push(obj);
    var obj2 = {
        "uname" : "admin2",
        "upassword" : "admin2" 
    }
    arr.push(obj2)
    
    var str = JSON.stringify(arr);
    fs.writeFile('./data/03.json',str,'utf8',function(err){   //如果写入成功,这个err为null
        // console.log(err);
        if(err){
            throw err;    //如果错误,将错误抛出
        }
        console.log('文件写入成功')
    
    
        // 如果文件不存在,会帮你去创建对应的文件,但是不会创建文件夹
    })

    同步写文件
    fs.writeFileSync(file, data[, options])

     

      4)追加文件

    
    异步的追加文件
    fs.appendFile(path, data[, options], callback)
    fs.appendFile("./data/04.json","hello world","utf8",function(err){
        console.log(err);
        console.log('OK')
    })
    
    同步的追加文件
    fs.appendFileSync(path, data[, options])

     

      5)创建文件夹

    异步的创建文件夹
    fs.mkdir("./data02",function(err){
        console.log(err);   //node会报错,但是错误都不会抛出,不会影响后续代码的执行
        console.log('OK');
    })
    
    同步的创建文件夹
    fs.mkdirSync(path[, options])

     

      7)读文件夹

    异步读文件夹
    fs.readdir(path[, options], callback)
    fs.readdir("./data",function(err,data){
        console.log(err);
        console.log(data);   //里面的文件以数组的形式表示出来,进行判断,判断是否是文件夹
        // 如果是文件夹,继续读文件夹,如果是文件,直接读文件,然后展示
    })
    
    同步的读文件夹
    fs.readdirSync(path[, options])

     

      8)文件夹是否存在

    异步判断文件或者文件夹是否存在
    fs.access(path[, mode], callback)   能否判断文件夹是否存在
    fs.access("./data",function(err){   //这个方法是可以判断文件和文件夹是否存在
        console.log(err);
        console.log('OK');
    })
    
    同步判断文件或者文件夹是否存在
    fs.accessSync(path[, mode])

     

      9) 文件信息

    fs.stat("./data",function(err,stats){
        console.log(err);
        // console.log(stats.isDirectory());
      
    //    获取文件的大小;
     if(stats.isDirectory()){
      console.log(
    '是文件夹')
     }
    else{
      console.log(
    '是文件')
     }
        console.log(stats.size);
    //    获取文件最后一次访问的时间;
        console.log(stats.atime.toLocaleString());
    //    文件创建的时间;
        console.log(stats.birthtime.toLocaleString());
    //    文件最后一次修改时间;
        console.log(stats.mtime.toLocaleString());
    //    状态发生变化的时间;
        console.log(stats.ctime.toLocaleString())
    //判断是否是目录;是返回true;不是返回false;
        console.log(stats.isFile())

        console.log(stats.isDirectory()) })
     

    })

      

      10)文件流

      想象一下,如果把文件读取比作向一个池子里抽水,同步会阻塞程序,异步会等待结果,如果这个池子特别大怎么办?有三峡水库那么大怎么办?你要等到多久才能喝到抽的水?因此便会有了文件流,文件流就好比你一边抽一边取,不用等池子满了再用一样方便。

    // 文件流   适用于比较大内容
    
    var fs = require("fs");
    
    // 读文件的流
    var rs = fs.createReadStream("./../0225-3node文件系统-1.mp4");
    // 写文件的流
    var ws = fs.createWriteStream("./video.mp4");
    
    var stats = fs.statSync("./../0225-3node文件系统-1.mp4");
    
    // console.log(stats);
    var size = stats.size;
    
    // 通过buffer进行传输
    var data = 0;
    rs.on("data",function(chunk){
        data = data + chunk.length;
        console.log('传输的进度' + (data/size) * 100 + "%");
    
        ws.write(chunk);
    })
    rs.on("end",function(){
        console.log('文件读写完成');
        ws.end();
    })


    // buffer 就是一个对象,有点像数组

    
    

    var buf = new Buffer(5); //每一个存的值是16进制的
    buf[0] = 0x68;
    buf[1] = 0x65;
    buf[2] = 0x6c;
    buf[3] = 0x6c;
    buf[4] = 0x6f;

     2.http的模块:

     

    // 引入http的模块
    var http = require("http");
    
    // 创建一个服务
    var count = 0;
    http.createServer(function(request,response){
        count ++;
        console.log('hello world');
        response.end(count.toString())
    }).listen(3000)

     

    3. path模块:
      1)获取所在路径(.dirname)
    var path = require('path');
    var filepath = '/tmp/demo/js/test.js';
     
    
    console.log( path.dirname(filepath) )
    // 输出:/tmp/demo/js

      2)获取文件名:(basename)

    var path = require('path');
    
    console.log( path.basename('/tmp/demo/js/test.js') );
    // 输出:test.js
    
    //如果只想获取文件名,单不包括文件扩展呢?可以用上第二个参数。
    console.log( path.basename('/tmp/demo/js/test.js', '.js') );
    // 输出:test 
    
    //如果没有文件,获取路径的最后一位
    console.log( path.basename('/tmp/demo/js/test/') );
    // 输出:test
     
    
    console.log( path.basename('/tmp/demo/js/test') );
    // 输出:test

      3) 获取文件扩展名

    var path = require('path');
    var filepath = '/tmp/demo/js/test.js';
     
    
    console.log( path.extname(filepath) );
    // 输出:.js

     

    5.node服务器

     基本创建步骤:
    var http = require("http");   //引入http的模块,用来提供服务
    var fs = require("fs");
    
    var server = http.createServer();    //创建一个服务器
    
    
    //server监听request事件,callback
    server.on('request',function(request,response){
        response.writeHead(200,{"Content-Type" : "text/html;charset=utf8"});    // 注意:图片,script,css,文本,html都要与之对应  
         
        // // 输出对应的中文的时候,要有对应的格式和对应的编码
    
        // response.write("<h1>你好</h1>");
    
        // response.end("<h2>hello world</h2>");   //结束,结束必须有,不然表示这个请求和响应没有完成
    
    //接口设置
        if(request.url == "/login.html" && request.method == "GET"){
            // response.end("这个是登录界面")
            fs.readFile("./login.html",'utf8',function(err,data){
                response.end(data);
            })
    
        }else if(request.url == "/register" && request.method == "GET"){
            response.end("这个是注册界面")
    
        }
        else if(request.url == "/login" && request.method == "POST"){
            response.end("登录成功")
        }
    
        else {
            response.end("404");
        }
    
    
    });
    
    
    // 服务搭建完成,监听端口
    server.listen(8888);    //ctrl+c   停止
    console.log('服务运行在localhost:8888')
     demo:(注册/登录/首页--实现增删改查)
      1.接口文档

      2.服务器部分:

    var http =  require("http");
    var fs = require("fs");
    var querystring = require("querystring");
    var url = require("url");
    var path = require("path");
    
    var server = http.createServer();
    
    server.on("request",function(req,res){
        var urlObj = url.parse(req.url,true);    //地址栏格式化成对象
        var pathname = urlObj.pathname;            //pathname:当前页面的相对路径
        var query = urlObj.query;    
        console.log(pathname);                    //获取到地址栏的参数    
        
        //静态伺服
        if(pathname == "/formlogin.html" && req.method == "GET"){
            fs.readFile("./formlogin.html","utf8",function(err,data){
                // console.log(err);
                res.end(data);
            })
        }
        else if(pathname == "/register.html" && req.method == "GET"){
            fs.readFile("./register.html","utf8",function(err,data){
                // console.log(err);
                res.end(data);
            })
        }
        else if(pathname == "/shouye.html" && req.method == "GET"){
            fs.readFile("./shouye.html",function(err,data){
                // console.log(err);
                res.end(data);
            })
        }
        //js
        else if(pathname == "/js/formlogin.js" && req.method == "GET"){
            fs.readFile("./js/formlogin.js","utf8",function(err,data){
                // console.log(err);
                res.end(data);
            })
        }
        else if(pathname == "/js/register.js" && req.method == "GET"){
            fs.readFile("./js/register.js","utf8",function(err,data){
                res.end(data);
            })
        }else if(pathname == "/js/shouye.js" && req.method == "GET"){
            fs.readFile("./js/shouye.js","utf8",function(err,data){
                res.end(data);
            })
        }
        //css
        else if(pathname == "/css/formlogin.css" && req.method == "GET"){
            fs.readFile("./css/formlogin.css","utf8",function(err,data){
                res.end(data);
            })
        }
        else if(pathname == "/css/shouye.css" && req.method == "GET"){
            fs.readFile("./css/shouye.css","utf8",function(err,data){
                res.end(data);
            })
        }
    
        //注册失焦验证
        else if( pathname == "/register_validation" && req.method == "GET"){
                fs.readFile("./data/03.json","utf8",function(err,datas){
                    var data = JSON.parse(datas);
                    // console.log(data)
                    var flag = true;
                    //遍历数组,有相同名字的返回false,输出0;没有相同名字的,输出1;
                    for(var i = 0; i < data.length; i++){
                        // console.log(query.uname);
                        // console.log(data[i].uname);
                         if(data[i].uname == query.uname){
                            // res.end("0");   //用户名已存在
                            flag = false;
                            break;
                        }
                    }    
                    if(flag) {
                        res.end("1");   //用户名可以使用
                    }else {
                        res.end("0");   //用户名
                    }                
                        
                })
        }
        //登录验证
        else if(pathname == "/login" && req.method == "POST"){
            // console.log('1111')
            var data ="";
            req.on("data",function(chunk){
                data += chunk;
            })
            req.on('end',function(){
                var dataobj = querystring.parse(data);
                // console.log(dataobj);
                fs.readFile("./data/03.json","utf8",function(err,data){
                    data_login = JSON.parse(data);
                    // console.log(data_login);
                    // console.log(dataobj.uname);
                    // console.log(dataobj.upassword);
                    for(var i = 0; i < data_login.length; i++){
                        if(data_login[i].uname == dataobj.uname){
                            if(data_login[i].upassword == dataobj.upassword){
                                 res.end("1");   //登录成功
                            }else {
                                    res.end("2");   //密码错误
                            }    
                        }
                    }
                    res.end("0");   //参数错误
                });    
            });                
        }    
        
        //注册按钮
        else if(pathname == "/register" && req.method == "POST"){
            var data ="";
            req.on("data",function(chunk){
                data += chunk;
            })
            console.log("1")
            req.on('end',function(){
                var data_qt = querystring.parse(data);        //用户输入的数据转化为对象的形式
                console.log(data_qt);
                fs.readFile("./data/03.json","utf8",function(err,data){
                    // console.log(err);
                    // console.log(data);
                    
                    if(data_qt.uname && data_qt.upassword){
                        var data_ht = JSON.parse(data);    
                        console.log(data_ht);        //后台数据字符串转化为对象的形式
                        data_ht.push(data_qt);
                        var data_ht_str = JSON.stringify(data_ht)
                         fs.writeFile("./data/03.json",data_ht_str,"utf8",function(){
                             res.end("1")        //注册成功
                         });
                        
                    }else {
                        res.end("0");    //参数错误
                    }
                });    
            });                
        }    
    
        //获取主页数据
        else if( pathname == "/index_getdata" && req.method == "GET" ){
            fs.access("./data/"+query.uname+".json",function(err){
                if(err){
                    fs.writeFile("./data/"+query.uname+".json","[]",function(err){
                        fs.readFile("./data/"+query.uname+".json","utf8",function(err,data){
                            var datas = '{"margin":"ok","data":'+data+'}';
                            // var bm =JSON.parse(datas); 
                            // console.log(bm)
                            res.end(datas);
                        })
                    })
                }else {
                    fs.readFile("./data/"+query.uname+".json","utf8",function(err,data){
                                var datas = '{"margin":"ok","data":'+data+'}'; 
                            // var bm = JSON.parse(datas); 
                            // console.log(bm)
                            res.end(datas);
                    })
                }
            })        
        }
    
    
        //增加
        else if(pathname == "/add_data" && req.method == "POST"){
    
            var data ="";
            req.on("data",function(chunk){                    //监听前台数据的变化
                data += chunk;    
                console.log(data);                        
            })
                                        //字符串
            req.on('end',function(){
                var data_qt = querystring.parse(data);        //用户输入的数据转化为对象的形式
                console.log(data_qt);
                fs.readFile("./data/"+data_qt.uname+".json","utf8",function(err,datas){
                    console.log(err);
                    // console.log(data);
                    var data_ht = JSON.parse(datas);        //后台数据字符串转化为对象的形式
                    console.log(data_ht);
    
                    if(data_ht.length == 0){
                        data = {
                           uname : data_qt.uname,
                           pid:0,
                           name:data_qt.name,
                           sex:data_qt.sex,
                           age:data_qt.age,
                           mail:data_qt.mail,
                           phone: data_qt.phone
                        }    
                        data_ht.push(data);
                        var data_ht_str = JSON.stringify(data_ht)
                        fs.writeFile("./data/"+data_qt.uname+".json",data_ht_str,"utf8",function(){
                            res.end("1")        //注册成功
                        });
                    }else {
                        data = {
                           uname : data_qt.uname,
                           pid:data_ht[data_ht.length-1].pid+1,
                           name:data_qt.name,
                           sex:data_qt.sex,
                           age:data_qt.age,
                           mail:data_qt.mail,
                           phone: data_qt.phone
                        }
                        data_ht.push(data);
                        var data_ht_str = JSON.stringify(data_ht)
                        fs.writeFile("./data/"+data_qt.uname+".json",data_ht_str,"utf8",function(){
                            res.end("1")        //注册成功
                        });
                    }    
                    
                });    
            });                
        }    
    
        //删除按钮
        else if( pathname == "/remove_data" && req.method == "GET" ){
            fs.readFile("./data/"+query.uname+".json","utf8",function(err,data){
                var data = JSON.parse(data);
                var uname = query.uname;
                console.log(data);
                for (var i = 0; i < data.length; i++) {
                    if (data[i].pid == query.pid) {
                        // data.splice(i,1);
                        console.log(i)
                        break;
                    }
                }
                    // console.log(i)
                    data.splice(i,1);
                    // console.log(data);
                    var data_str = JSON.stringify(data);
                    // console.log(data_str);
                    fs.writeFile('./data/' + uname + ".json",data_str,function(err){
                        res.end("1");
                    })
                    // console.log(data);
            })
                
        }
        //修改
        else if(pathname == "/revise_data" && req.method == "POST"){
            var data_qt = "";
            req.on("data",function(chunk){
                data_qt += chunk;
            })
            // console.log('1');
            req.on('end',function(err){
                // console.log("2");
                  var data_qt_obj = querystring.parse(data_qt);    //用户输入的数据转化为对象的形式
                     // console.log(data_qt_obj)
         //          var uname = data_qt_obj.uname;
         //          var pid = data_qt_obj.pid;
                  fs.readFile('./data/' + data_qt_obj.uname + ".json",'utf8',function(err,data){
                      var data_ht_obj = JSON.parse(data);
                      // console.log(data_ht_obj);
                      for(var i = 0;i < data_ht_obj.length;i++){
                          if(data_ht_obj[i].pid == data_qt_obj.pid){
                              break;
                          }
                      }
                      if(data_qt_obj.name){
                          data_ht_obj[i].name = data_qt_obj.name
                      }
                      if(data_qt_obj.sex){
                          data_ht_obj[i].sex = data_qt_obj.sex
                      }
                      if(data_qt_obj.age){
                          data_ht_obj[i].age = data_qt_obj.age
                      }
                      if(data_qt_obj.mail){
                          data_ht_obj[i].mail = data_qt_obj.mail
                      }
                      if(data_qt_obj.phone){
                          data_ht_obj[i].phone = data_qt_obj.phone
                      }
                      var str = JSON.stringify(data_ht_obj);
                      fs.writeFile('./data/' + data_qt_obj.uname + ".json",str,function(err){
                        res.end("1");
                    })
                  })
              })
        }
    
    
    
    })
    
    server.listen(3535);
    console.log("server running in localhost:3535");
    console.log("
    ")
  • 相关阅读:
    HDU X mod f(x)(题解注释)
    hdu 3555 Bomb(不要49,数位DP)
    hdu 2089 不要62(入门数位dp)
    暑假练习赛 003 B Chris and Road
    暑假练习赛 003 F Mishka and trip
    暑假练习赛 003 A Spider Man
    linux:关于Linux系统中 CPU Memory IO Network的性能监测
    linux TCP数据包重传过程----小结
    linux TCP头部的构造的简单分析
    linux TCP数据包封装在SKB的过程分析
  • 原文地址:https://www.cnblogs.com/1234wu/p/10472905.html
Copyright © 2011-2022 走看看