成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

node.js入門(mén)學(xué)習(xí)筆記整理——基礎(chǔ)篇

Tamic / 2723人閱讀

摘要:的介紹一般是這樣在中,類(lèi)是隨內(nèi)核一起發(fā)布的核心庫(kù)。庫(kù)為帶來(lái)了一種存儲(chǔ)原始數(shù)據(jù)的方法,可以讓處理二進(jìn)制數(shù)據(jù),每當(dāng)需要在中處理操作中移動(dòng)的數(shù)據(jù)時(shí),就有可能使用庫(kù)。這樣傳遞數(shù)據(jù)會(huì)更快。

零、開(kāi)始之前 1、 首先解釋一下node.js是什么? 2、node.js和javascript有什么不同?

1)因?yàn)閖avascript主要是用在browser,而node.js是在server或者你的電腦上寫(xiě),所以就不會(huì)有window / document這兩個(gè)變量,取而代之的是global / process.
global和window一樣,也有很多內(nèi)置的function和variables,比如setTimeout() / setInterval() / console..., 不過(guò)也有很多不同,這個(gè)后面會(huì)慢慢講;

一、Modules—— require() & exports

node.js里很重要的一個(gè)概念就是modules。除了一些core modules(比如events/http/fs/url...), 還可以用require()來(lái)引進(jìn)一些自定義的modules。

比如:

//stuff.js
var counter = function(arr){
    return "There are "+ arr.length+ " arguments."
   };

var adder = function(a,b){
    return `the sum is ${a+b};`
   };

var pi = 3.1415926;

如果要在其他的file里用這個(gè)counter function應(yīng)該怎么做呢?
在stuff.js后面加上:

//第一種方法
//modules.exports是一個(gè)object對(duì)象
modules.exports.counter = counter;
modules.exports.adder = adder;
modules.exports.pi = pi;

上面的方法意思是到了,但是比較復(fù)雜,我們可以用對(duì)象的方式來(lái)寫(xiě)modules.exports

//第二種方法
modules.exports = {
    counter: counter,
    adder: adder,
    pi: pi
  }

還有一種辦法直接寫(xiě)在上面的functions里:

modules.exports.counter = function(arr){
    return "There are "+ arr.length+ " arguments."
   };

modules.exports.adder = function(a,b){
    return `the sum is ${a+b};`
   };

modules.exports.pi = 3.1415926;

然后要引用的時(shí)候使用require():

//main.js

var stuff = require("./stuff"); //可以不用寫(xiě)extension name,node自己會(huì)補(bǔ)上;
//使用一下:
console.log(stuff.counter(["hello", "world"]);
console.log(stuff.adder(5, stuff.pi);
二、EventEmitter類(lèi)

在node.js里,有一個(gè)core module是event,event里只有一個(gè)對(duì)象,就是EventEmitter, 主要用于封裝事件觸發(fā)和事件監(jiān)聽(tīng)器的功能(使用javascript里的觀(guān)察者模式)。
如果用過(guò)jquery的話(huà),對(duì)這個(gè)格式一定不陌生:

button.on("click", function(){alert("clicked!");}

其實(shí)node里的EventEmitter和jQuery的這個(gè)事件監(jiān)聽(tīng)函數(shù)的寫(xiě)法也很類(lèi)似:

//首先引入EventEmitter對(duì)象
//EventEmitter是一個(gè)constructor,可以使用原型繼承
var eventEmitter = require("event").EventEmitter;
var event = new eventEmitter();
//綁定事件
event.on("data", function(str){
    console.log("something here: "+ str.toString());
   };
//觸發(fā)事件
//前一個(gè)param是event的名字,后一個(gè)是callback函數(shù)需要的變量
event.emit("data", "Tom wants sth to eat.");

前面提到EventEmitter其實(shí)是一個(gè)constructor,可以通過(guò)prototype繼承;
我們現(xiàn)在用util這個(gè)module來(lái)實(shí)現(xiàn)node里的inherits:

var event = require("event");
var util = require("util");

//創(chuàng)造一個(gè)person的constructor,一會(huì)來(lái)繼承eventEmitter;
var Person = function(name){
    this.name = name;
   };
//util.inherits用來(lái)繼承,注意兩個(gè)params的順序;
util.inherits(Person, event.EventEmitter);

//現(xiàn)在我們來(lái)new兩個(gè)person實(shí)例出來(lái):
var james = new Person("james");
var ellen = new Person("ellen");
//放在一個(gè)叫people的array里:
var people = [james, ellen];
//現(xiàn)在用eventEmitter里的on方法綁定事件;
//因?yàn)镻erson實(shí)例已經(jīng)繼承,所以可以使用
people.forEach(function(person){
  person.on("speak", function(str){
    console.log(`${person} says ${str}`);
  });
});
//觸發(fā)事件
james.emit("speak", "good morning!");
ellen.emit("speak", "good evening!");
三、fs (file system) 類(lèi)

fs類(lèi)主要是用來(lái)處理文件的,有非常多的方法,但在這個(gè)小教程里只涉及read和write兩項(xiàng)。
首先我們來(lái)區(qū)分一下“同步”和“異步”的概念:
“同步”—— blocking; 解析器會(huì)一步一步地解析你的code,如果前面那行沒(méi)操作完就不會(huì)操作后面那行;
“異步”——non-blocking;解析器解析完這行代碼之前,不會(huì)妨礙到后面代碼的進(jìn)行,在異步處理完后通過(guò)callback函數(shù)對(duì)結(jié)果進(jìn)行處理,因此,異步的性能比同步會(huì)很多。

//node中同步read和write的寫(xiě)法:
var fs = require("fs");
//同步是"readFileSync"
var readMe = fs.readFileSync("input.txt", "utf8");
fs.write("output.txt", readMe);

//異步:
//err是出現(xiàn)的錯(cuò)誤,data是readFile后讀取到的數(shù)據(jù)
fs.readFile("input.txt", "utf8", function(err, data){
    if(err){
        console.error(err);
     }else{
        fs.writeFile("output.txt", data);
     }

可以看到,運(yùn)用fs的callback函數(shù),可以直接在readFile里寫(xiě)writeFile, 不需要重新定義變量。

再寫(xiě)一個(gè)fs中的建立目錄和移除目錄的方法,同樣有同步和異步兩種方式:

var fs = require("fs");

//make a directory sync
fs.mkdirSync("stuff");
//delete a directory sync
fs.rmdirSync("stuff");
//make a directory async
fs.mkdir("stuff", function(){
    fs.readFile("readMe.txt", "utf8", function(err,data){
        fs.writeFile("./stuff/writeMe/txt", data);
    });
});
//remove a directory async
//you must first remove all files in this directory, then you can delete this folder
fs.unlink("./stuff/writeMe.txt", function(){
    fs.rmdir("stuff");
})
四、Stream類(lèi)

在解釋stream之前,首先我們來(lái)想一想為什么要有readable stream和writable stream呢? 明明fs類(lèi)里就有readFile和writeFile的方法啊,何必還要再添加stream來(lái)找麻煩呢?

要知道這兩個(gè)之間的不同,讓我們來(lái)理一下"buffer"的概念。
buffer的介紹一般是這樣:

在Node.js中,Buffer類(lèi)是隨Node內(nèi)核一起發(fā)布的核心庫(kù)。Buffer庫(kù)為Node.js帶來(lái)了一種存儲(chǔ)原始數(shù)據(jù)的方法,可以讓Nodejs處理二進(jìn)制數(shù)據(jù),每當(dāng)需要在Nodejs中處理I/O操作中移動(dòng)的數(shù)據(jù)時(shí),就有可能使用Buffer庫(kù)。

簡(jiǎn)單來(lái)說(shuō),buffer就是一個(gè)處理二進(jìn)制數(shù)據(jù)的緩沖模塊,那和stream又有什么關(guān)系呢?
可以看下下面的圖:

這張圖里,可以把很大的一塊data進(jìn)行肢解,然后儲(chǔ)存到buffer中,形成一個(gè)個(gè)的相對(duì)比較小的data chunk;

在這張圖里,chunk one by one向前傳遞就成了stream。

所以回到我們最初的問(wèn)題,用readable stream和fs里的readFile有什么不同?

readFile是等一個(gè)file全部讀完之后才fire callback函數(shù),進(jìn)行下一步動(dòng)作;而stream是通過(guò)把file里的數(shù)據(jù)分成很多很多個(gè)小的chunk, 每次callback函數(shù)感知到data chunk的時(shí)候就會(huì)觸發(fā)。這樣傳遞數(shù)據(jù)會(huì)更快。

1、Readable stream
var fs  = require("fs");
var myReadStream = fs.createReadStream(__dirname + "/input.txt", "utf8"); 
//這里的‘utf8"如果不加的話(huà)會(huì)解碼成二進(jìn)制(因?yàn)閎uffer)

myReadStream.on("data", function(chunk){
    console.log("new chunk received");
    console.log(chunk);
});
//stream也繼承eventEmitter
//每次感知到data chunk就會(huì)觸發(fā),不需要等到整個(gè)file都讀完
2、Writable stream
//和readable stream類(lèi)似
//會(huì)創(chuàng)造出來(lái)一個(gè)output.txt在目錄下
var fs  = require("fs");
var myReadStream = fs.createReadStream(__dirname + "/input.txt", "utf8");
var myWriteStream = fs.createWriteStream(__dirname + "/output.txt");

myReadStream.on("data", function(chunk){
    console.log("new chunk received");
    myWriteStream.write(chunk);
});
3、pipe

因?yàn)榘裷eadable stream轉(zhuǎn)成writable stream在node.js里非常常見(jiàn),所以有一個(gè)更elegant的辦法就是用pipe:

var fs = require("fs");
var myReadStream = fs.createReadStream(__dirname + "/input.txt", "utf8");
var myWriteStream = fs.createWriteStream(__dirname + "/output.txt");
//pipe只能從可讀流出發(fā),不能從可寫(xiě)流出發(fā)
myReadStream.pipe(myWriteStream);

如果加上web server就可以這么寫(xiě):

var fs  = require("fs");
var http = require("http");

var server = http.createServer(function(req, res){
    console.log("request was made: "+ req.url);
    res.writeHead(200, {"Content-Type": "text/plain"});
    var myReadStream = fs.createReadStream(__dirname + "/input.txt", "utf8");
    myReadStream.pipe(res);
    //response obj is writable 
});

server.listen(3000);
console.log("listen to port 3000");

如果要傳遞的數(shù)據(jù)是html格式的話(huà):

var fs  = require("fs");
var http = require("http");

var server = http.createServer(function(req, res){
    console.log("request was made: "+ req.url);
    //html格式也可以用stream傳遞,用pipe把可讀流轉(zhuǎn)成可寫(xiě)流
    res.writeHead(200, {"Content-Type": "text/html"});
    var myReadStream = fs.createReadStream(__dirname + "/index.html", "utf8");
    myReadStream.pipe(res);
    //response obj is writable 
});

server.listen(3000);
console.log("listen to port 3000");

如果傳遞的數(shù)據(jù)是json的話(huà):

//不使用stream,直接在res.end()里面?zhèn)鬟f
//但是要注意的是,end()里面只接受string,不能把object直接放進(jìn)去
var fs  = require("fs");
var http = require("http");

var server = http.createServer(function(req, res){
    console.log("request was made: "+ req.url);
    res.writeHead(200, {"Content-Type": "application/json"});
    var myobj = {
        name: "Ryu",
        job: "ninja",
        age: 29
    };
    res.end(JSON.stringify(myobj));
});

server.listen(3001);
console.log("listen to port 3001");
五、Router

介紹一個(gè)很簡(jiǎn)單的router的使用辦法,只要用if判斷req.url,然后用stream寫(xiě)入即可:

var http = require("http");
var fs = require("fs");

var server = http.createServer(function(req,res){
    console.log("request was made: "+ req.url);
    if(req.url === "/home" || req.url === "/"){
        res.writeHead(200, {"Content-Type" : "text/html"});
//用fs的pipe把readable stream改成writable stream
        fs.createReadStream(__dirname +"/index.html").pipe(res);
    }else if(req.url === "/sample"){
        res.writeHead(200, {"Content-Type": "text/html"});
        fs.createReadStream(__dirname + "/sample.html").pipe(res);
    }else if(req.url === "/api/ninjas"){
        var ninjas = [{name: "ryu", age: 29}, {name: "yoshi",age:32 }];
        res.writeHead(200, {"Content-Type": "application/json"});
        res.end(JSON.stringify(ninjas));
    }
//其實(shí)還可以再寫(xiě)一個(gè)404 page
});

server.listen(3000);
console.log("now listening to port 3000");

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/82392.html

相關(guān)文章

  • 前端相關(guān)大雜燴

    摘要:希望幫助更多的前端愛(ài)好者學(xué)習(xí)。前端開(kāi)發(fā)者指南作者科迪林黎,由前端大師傾情贊助。翻譯最佳實(shí)踐譯者張捷滬江前端開(kāi)發(fā)工程師當(dāng)你問(wèn)起有關(guān)與時(shí),老司機(jī)們首先就會(huì)告訴你其實(shí)是個(gè)沒(méi)有網(wǎng)絡(luò)請(qǐng)求功能的庫(kù)。 前端基礎(chǔ)面試題(JS部分) 前端基礎(chǔ)面試題(JS部分) 學(xué)習(xí) React.js 比你想象的要簡(jiǎn)單 原文地址:Learning React.js is easier than you think 原文作...

    fuyi501 評(píng)論0 收藏0
  • 前端文檔收集

    摘要:系列種優(yōu)化頁(yè)面加載速度的方法隨筆分類(lèi)中個(gè)最重要的技術(shù)點(diǎn)常用整理網(wǎng)頁(yè)性能管理詳解離線(xiàn)緩存簡(jiǎn)介系列編寫(xiě)高性能有趣的原生數(shù)組函數(shù)數(shù)據(jù)訪(fǎng)問(wèn)性能優(yōu)化方案實(shí)現(xiàn)的大排序算法一怪對(duì)象常用方法函數(shù)收集數(shù)組的操作面向?qū)ο蠛驮屠^承中關(guān)鍵詞的優(yōu)雅解釋淺談系列 H5系列 10種優(yōu)化頁(yè)面加載速度的方法 隨筆分類(lèi) - HTML5 HTML5中40個(gè)最重要的技術(shù)點(diǎn) 常用meta整理 網(wǎng)頁(yè)性能管理詳解 HTML5 ...

    jsbintask 評(píng)論0 收藏0
  • 前端文檔收集

    摘要:系列種優(yōu)化頁(yè)面加載速度的方法隨筆分類(lèi)中個(gè)最重要的技術(shù)點(diǎn)常用整理網(wǎng)頁(yè)性能管理詳解離線(xiàn)緩存簡(jiǎn)介系列編寫(xiě)高性能有趣的原生數(shù)組函數(shù)數(shù)據(jù)訪(fǎng)問(wèn)性能優(yōu)化方案實(shí)現(xiàn)的大排序算法一怪對(duì)象常用方法函數(shù)收集數(shù)組的操作面向?qū)ο蠛驮屠^承中關(guān)鍵詞的優(yōu)雅解釋淺談系列 H5系列 10種優(yōu)化頁(yè)面加載速度的方法 隨筆分類(lèi) - HTML5 HTML5中40個(gè)最重要的技術(shù)點(diǎn) 常用meta整理 網(wǎng)頁(yè)性能管理詳解 HTML5 ...

    muddyway 評(píng)論0 收藏0
  • webpack入門(mén)學(xué)習(xí)手記(二)

    摘要:例如現(xiàn)在的入門(mén)學(xué)習(xí)手記系列。收到粉絲留言和打賞的喜悅。安裝上一篇入門(mén)學(xué)習(xí)手記一,主要是介紹了的核心概念,是整個(gè)學(xué)習(xí)過(guò)程的基礎(chǔ)知識(shí)。新生成的類(lèi)似如下入門(mén)學(xué)習(xí)手記因?yàn)樯傻膬?nèi)容過(guò)多,我直接省略掉了。 showImg(https://segmentfault.com/img/bVbk5Nd?w=1150&h=599); 本人微信公眾號(hào):前端修煉之路,歡迎關(guān)注。 最近開(kāi)始想要維護(hù)一個(gè)個(gè)人的公眾...

    Joyven 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<