• 浅析node.js


      大家好,今天来给大家讨论node.js这个东西,说起这个东西啊,可能大家已经很熟悉了,因为现在市场上运用的越来越广泛,毕竟它的优点还是有目共睹的!

      那么,什么是node.js呢?官方给出了这样的定义:“node.js是一个基于Chrome V8引擎的JavaScript运行环境。Node.js使用了一个事件驱动、非阻塞式I/O的模型,使其轻量又高效“。这样我们就能知道node.js是一个运行环境,而且具有轻量又高效的特点。

      既然提到了运行环境,那么我们都知道浏览器也是一个运行环境,他们之间有没有区别呢?自然是有的,在浏览器安全环境下有一些安全性的限制,不允许调用底层的方法,但node环境允许调用底层的各种api,而且在node环境下我们是可以操作文件系统的(这个可厉害了!试想一下,如果浏览器能够使用文件系统,那么当你访问一个恶意网站时)!

      一般来说,node适合开发高并发的项目,一般在大型项目中作为中间层使用,搭node中间层的目的是解决高并发,同时解决性能问题,但是node本身也存在一些缺点:node处理大量计算时速度会比较慢!

      要想学好node,就一定要熟练使用npm,npm是一个node的包管理仓库,是世界上最大的开放源代码的生态系统,也是一个网站,也是一条命令

      这里介绍一些node的使用方法,当然了,大家需要先安装一下node,具体安装方法可以百度上来看,很多,也很简单!在此之前,我们要先说一下node中的模块问题,node有很多自己的模块,因为node遵循的是commonjs的规范,因此我们要使用内置模块时直接通过require引用就好了,比如我们使用http模块创建一个服务器

    const http = require("http")
    
    const server = http.createServer(req,res()=>{
       res.end("hello world") 
    })
    res.listen("9000")

    除了内置模块。npm上还有很多第三方模块,我们可以通过下载来使用这些模块,可以通过npm  install  模块名 --global(可以简写为-g)来进行全局下载,npm install  模块  --save(-s)安装项目依赖

      好了,说完模块问题,我们就可以来进行正式的npm命令使用了,首先我们应该去官网注册有个npm账号,当我们写了一个不错的模块时,想要把该模块上传到npm网站时我们就可以这样操作

    //首先在cmd中进去我们的项目文件夹
    c/d/e/://进入什么盘(c还是d还是e)
    cd  file//进去你的模块文件夹
    npm  init
    
    //执行完这行命令后,会生成一个package.json的文件夹,文件夹中的name名要唯一,当这个文件夹存在时node就是一个包了
    
    npm  adduser 输入账号密码
    
    npm  publish  上传模块
    
    然后别人就可以通过npm  install 模块名来下载你的模块了!

       因为npm是国外的网站,可能有时候我们下载需要的资源时网速会有点那么不尽人意,这个时候我们就需要用到nrm这个模块了

    npm install  nrm  -g//全局安装
    
    nrm  ls  //查看可以使用的源
    
    nrm test  源名  //测试单个源的速度
    
    nrm  use  源名  //切换到你要使用的源
    
    
    //这样我们就可以把源切换到下载速度较快的源,就会加快好多了

      关于yarn:

    yarn类似于npm的替代品,与npm相差无几,但是相比npm有以下几个优点:

       1>.yarn是异步的所以比npm快
       2>.团队编程中使用yarn,可以保证版本号一致,开发时不出错
       3>.本地的包会有缓存,安装本本地存在的包时会非常快

    值得注意的是用yarn下载模块的时候是通过yarn add  模块名    来下载的,而且不需要加-s。直接代表npm install 模块名  --save

    接下来我们来介绍一下node中常用的几个模块:

    1.url模块:

    url.parse(urlString[, parseQueryString[, slashesDenoteHost]])
    url.format(urlObject)
    url.resolve(from, to)

    代码使用如下

    const url=require("url");
    //url.parse()解析url,返回值是URLobject;
    Const    result=url.parse("https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=node&oq=node&rsv_pq=aea4b4650005e274&rsv_t=b6efVwyWo9RLoHnJougYq4rPh%2B83TZcEX%2BdoFLqN8zcpvB2fgErBjdboWPo&rqlang=cn&rsv_enter=0",true);
    //urlformat.根据URLobject生成URL
    const rs=url.format(result);
     console.log(rs);
    //生成相对路径或绝对路径的一种方法
    console.log(url.resolve("http://www.baidu.com/a/b/c","d"));
    //网址是/a/b/c
    //<a href="/d">跳转到d</a>
    //  结果是http://www.baidu.com/a/b/d
    console.log(url.resolve("http://www.baudu.com/a/b/c","/d"));
    //网页地址是/a/b/c
    // <a href="/d">跳转到d</a>
    //结果是http://www.baidu.com/d

    2、Query String
    querystring.escape(str)对给定的字符串进行编码
    querystring.parse(str[, sep[, eq[, options]]])要解析的url
    querystring.stringify(obj[, sep[, eq[, options]]])把对象转换成jQuery对象
    querystring.unescape(str)对给定的str解码
    Querystring.js代码:

    const querystring = require("querystring");
    const str = "name%dell!age%28!gender%male";
    //querystring.parse 对querys字符串进行解析,seprator=&,equal=
    const result = querystring.parse(str,"!","%");
    //querystring.stringify 把对象转化成query字符串
    console.log(querystring.stringify(result, "!", "%"));
    const newStr = "a=1=2=3";
    console.log(querystring.unescape(querystring.escape(newStr)));

    3、HTTP模块

      HTTP小爬虫 cheerio    Request方法(扩展)
    http.js代码

    const http = require("http");//引入http核心模块
    const cheerio = require('cheerio');//引入cheerio
    const fs = require("fs"); //
    //因为大多数请求都是get请求且不带请求主体,所以node.js提供了更便捷方法,该方法与http.requirest()唯一区别就是它设置请求方式为get自定调用req.end();
    http.get("http://www.easyvoa.com", (res) => {//http发送一个get请求
        if(res.statusCode == 200) {//200页面加载成功
            let str = "";
            res.setEncoding('utf8');//编码避免出现乱码
            res.on("data", (data) => {//监听data
                str += data;
            })
            res.on("end", () => {//触发end时间
                const $ = cheerio.load(str);//用了一个第三方模块,它的感觉像是jQuery实际上不是。只是帮助我们从一个字符串里找出我们想要的字符串。
                const titles = $(".title_a");把.title标签里面的内容存在titles
                let result = "";
                for (var i = 0; i < titles.length; i++) {
                    result += titles.eq(i).text() + '
    ';
                }
                fs.writeFileSync("list.text", result);
            })
        }
    })

    4、event模块

    EventEmitter      事件的参数    只执行一个的事件监听器

    代码如下:

    const EventEmitter=require("events");//EventEmitter它大写是因为events导出来的 是一个类,而类的首字母是大写
      class Wang extends EventEmitter{}// 自己定义了一个类继承了EvenEtmitter{}
      const wang=new Wang();//创建一个wang实例对象
      wang.on("change",()=>{//对象有一个on方法
          console.log("change");
      })
      //wang.once("change",()=>{//once只执行一次
      //console.log("haha");
      //})
      //wang.prependListener("change");
      //wang.removeAlListener("change");
    wang.emit("change");//emit触发事件

    5、fs模块

    得到文件与目录的信息:stat
    创建一个目录:mkdir
    创建文件并写入内容:writeFile,appendFile
    读取文件的内容:readFileSyn
    列出目录的东西:readdir
    重命名目录或文件:rename
    删除目录与文件:rmdir,unlink

    代码如下:

    const fs=require("fs");
        //得到文件与目录的信息
    // fs.stat("list.text",(err,stats)=>{
    //     console.log(stats.isDirectory());
    // })
          //创建一个目录
    // fs.mkdir("wang",(err)=>{
    //     if(err){
    //         console.log(error);
    //     }
    // })
            //创建文件并写入内容
    // fs.writeFile("lee.txt","content",(err)=>{
    //     console.log(err);
    // }      
    fs.writeFileSync("lee1.txt","1111")  
    fs.appendFileSync("lee1.txt","2222")
     console.log(123);
    // fs.readFile("lee1.txt",(err,data)=>{
    //    console.log(data);
    //})
    //fs.readdir("./",())
    //fs.readFile("lee1.txt",(err,data)=>{
    //    console.log(data);//<Buffer 31 31 31 31 32 32 32 32>
    //})
        //列出目录中的东西返回一个数组
    //fs.readdir("./",(err,list)=>{
    //    console.log(list);//返回一个数组
    //})
    // fs.rename("lee.txt","llelele.txt",()=>{})
    //重命名目录或文件[‘
    
     const read=fs.createReadStream("lee1.txt");
     const write=fs.createWriteStream("leecopy.txt");
     read.pipe(zlib.createGzip()).pipe(write);
    Server.js
       const server http.createServer((req,res)={
         If(req.url!==”/favicon.ico”){
            //Es6的解构赋值:
           const {pathname,query}=url.parse(req.url,true);
           (相当于:
    Pathname=url.parse(req.url,true).pathname;
    Query=url.parse(req.url,true).query;
    )
            If(req.url==”/”){//如果访问的是根目录则返回index
               res.end(“index”);
    }
    if(req.url==”/list”){//如果访问的是list则返回list
               res.end(“list”);
    }else{//否则返回404
       res.end(“404”);
    }
    
    }
    console.log(req.url);
    Res.end(“hello world”);
    })
     Server.listen(“3000”);

    6、关于socket:网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。持久连接,全双工,双向通信;常用于:消息提示,聊天工具
    代码:

    (1)服务器端:server.js
    //引入net模板,net中有socket
    const net=require("net");
    /*每个用户的连接,即保存所有用户*/
    const clients=[];
    //创建服务
    const server=net.createServer();
    //监听,当服务器被连接的时候,将连接用户保存在clients数组中
    server.on("connection",(client)=>{  
        //当一个用户连接进来时,我给用户一个id
        //将用户存入所有用户这个数组中
        client.id=clients.length;
        clients.push(client);
        //设置编码集合
        client.setEncoding("utf8");
        //监听用户是否给服务器发了这个数据
        //如果发送了数据,服务器要把数据转发给其他所有用户--->群聊,聊天室
        client.on("data",(data)=>{
            //将数据发送给其他所有用户
            for(var i=0;i<clients.length;i++){
                //如果存在,发送数据
                if(clients[i]){
                    //转发其他用户
                    clients[i].write(data);
                }
            }
        })
        //监听用户是否退出群聊
        client.on("close",(data)=>{
            //如果退出,将对应id用户移除
            clients[client.id]=null;
        })
        //监听用户连接是否失败
        client.on("error",(data)=>{
            //如果失败,将对应id用户移除
            clients[client.id]=null;
        })
        
        
    
    })
    server.listen("9000","127.0.0.1");
    (2)客户端:client.js
    //net中有socket
    const net=require("net");
    const readline=require("readline");
    //创建一个客户端
    const client=new net.Socket();
    //创建一个和命令行连接的接口(读和写)
    const rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout
    });
    
    //连接服务器
    client.connect("9000","127.0.0.1");
    //设置编码集合(buffer数据)
    client.setEncoding("utf8");
    //服务器传来数据,这里做监听
    client.on("data",(data)=>{
        
        console.log(data);    
    })
    //写一个数据,往服务器发送数据
    client.write("w_juan");
    //对命令行数的监听
    //监听控制台输入的内容发送给服务器
    rl.on("line",(input)=>{
        if(input==="quit"){
            //销毁
            rl.close();
            client.destory();
        }else{
            client.write(input);
        }
    })

    7、websocket:

    代码如下:

    1) 服务器端:
    const WebSocket = require('ws');
    const server = new WebSocket.Server({ port: 9000 });
    const clients = [];
    server.on('connection', (client) => {
        //存储用户
        client.id = clients.length;
        clients.push(client);
        client.on('message', (message) => {
            //一旦发送信息,将message传过去
            for (var i = 0; i < clients.length; i++) {
                clients[i] && clients[i].send(message);
                /*if(clients[i]){
                    //转发其他用户
                    clients[i].send(message);
                }*/
            }
        });
        client.on('error', () => {
            clients[client.id] = null;
        });
        client.on('close', () => {
            clients[client.id] = null;
        });
    });
    (2)客户端:
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>聊天室</title>
        </head>
        <body>
            <input type="text" id="input" />
            <button id="button" onclick="handleClick()">提交</button>
            <div id="div1"></div>
            <script type="text/javascript">
                var client = new WebSocket("ws://127.0.0.1:9000");
                input = document.getElementById("input");
                div1 = document.getElementById("div1");
                function handleClick() {
                    client.send(input.value);
                }
                client.onmessage = function(e) {
                    div1.innerHTML=e.data;
                }
            </script>
        </body>
    </html>

    好了,今天就先给大家写这么多吧,欢迎大家来交流!总之,node涵盖了前端和后端的很多内容,要想学好node,我们要深入理解前后端进行转换的思想,在学好js的基础上,尽可能的理解后端的运作及思维!祝大家早日拿下nodejs!



  • 相关阅读:
    java类研究(String)
    webservices
    LoadRunner(软件性能测试工具)
    java线程
    lucene solr
    java IO
    实现一个可变长数组
    [北大程序设计与算法]--虚函数与多态的实例
    A1155 Heap Paths [堆的dfs]
    A1154 Vertex Coloring
  • 原文地址:https://www.cnblogs.com/yunzhongjun/p/7875630.html
Copyright © 2020-2023  润新知