淺析node.js

  你們好,今天來給你們討論node.js這個東西,提及這個東西啊,可能你們已經很熟悉了,由於如今市場上運用的愈來愈普遍,畢竟它的優勢仍是有目共睹的!javascript

  那麼,什麼是node.js呢?官方給出了這樣的定義:「node.js是一個基於Chrome V8引擎的JavaScript運行環境。Node.js使用了一個事件驅動、非阻塞式I/O的模型,使其輕量又高效「。這樣咱們就能知道node.js是一個運行環境,並且具備輕量又高效的特色。html

  既然提到了運行環境,那麼咱們都知道瀏覽器也是一個運行環境,他們之間有沒有區別呢?天然是有的,在瀏覽器安全環境下有一些安全性的限制,不容許調用底層的方法,但node環境容許調用底層的各類api,並且在node環境下咱們是能夠操做文件系統的(這個可厲害了!試想一下,若是瀏覽器可以使用文件系統,那麼當你訪問一個惡意網站時)!前端

  通常來講,node適合開發高併發的項目,通常在大型項目中做爲中間層使用,搭node中間層的目的是解決高併發,同時解決性能問題,可是node自己也存在一些缺點:node處理大量計算時速度會比較慢!java

  要想學好node,就必定要熟練使用npm,npm是一個node的包管理倉庫,是世界上最大的開放源代碼的生態系統,也是一個網站,也是一條命令node

  這裏介紹一些node的使用方法,固然了,你們須要先安裝一下node,具體安裝方法能夠百度上來看,不少,也很簡單!在此以前,咱們要先說一下node中的模塊問題,node有不少本身的模塊,由於node遵循的是commonjs的規範,所以咱們要使用內置模塊時直接經過require引用就行了,好比咱們使用http模塊建立一個服務器web

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帳號,當咱們寫了一個不錯的模塊時,想要把該模塊上傳到npm網站時咱們就能夠這樣操做編程

//首先在cmd中進去咱們的項目文件夾
c/d/e/://進入什麼盤(c仍是d仍是e)
cd  file//進去你的模塊文件夾
npm  init

//執行完這行命令後,會生成一個package.json的文件夾,文件夾中的name名要惟一,當這個文件夾存在時node就是一個包了

npm  adduser 輸入帳號密碼

npm  publish  上傳模塊

而後別人就能夠經過npm  install 模塊名來下載你的模塊了!

   由於npm是國外的網站,可能有時候咱們下載須要的資源時網速會有點那麼不盡人意,這個時候咱們就須要用到nrm這個模塊了json

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

二、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)));

三、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() + '\n';
            }
            fs.writeFileSync("list.text", result);
        })
    }
})

四、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觸發事件

五、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」);

六、關於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);
    }
})

七、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!

相關文章
相關標籤/搜索