Nodejs API 學(xué)習(xí)系列(二)

本文的主要內(nèi)容是對nodejs提供的一些重要模塊粱锐,結(jié)合官方API進(jìn)行介紹,遇到精彩的文章,我會附在文中并標(biāo)明了出處绕德。主要包括如下8個模塊

  • buffer 模塊
  • dns 模塊
  • process 模塊
  • child_process 模塊
  • domain 模塊
  • cluster 模塊
  • event 模塊
  • util 模塊

轉(zhuǎn)載請注明出處,多謝支持~

buffer

關(guān)于中文亂碼

在node.js中摊阀,一個字符串的長度與根據(jù)該字符串所創(chuàng)建的緩存區(qū)的長度并不相同耻蛇,因?yàn)樵谟?jì)算字符串的長度時(shí),是以文字作為一個單位胞此,而在計(jì)算緩存區(qū)的長度時(shí)城丧,是以字節(jié)作為一個單位。

比如針對 ”我喜愛編程”這個字符串豌鹤,該字符串對象的length屬性值與根據(jù)該字符串創(chuàng)建的buffer對象的length屬性值并不相同亡哄。因?yàn)樽址畬ο蟮膌ength屬性值獲取的是文字個數(shù),而buffer對象的length屬性值獲取的是緩存區(qū)的長度布疙,即緩存區(qū)中的字節(jié)蚊惯。

var str = '勇士隊(duì)加油';
console.log(str.length);//5

var buf = new Buffer(str);
console.log(buf.length);//15

另外,可以使用0開始的序號來取出字符串對象或緩存區(qū)中的數(shù)據(jù)灵临。但是截型,在獲取數(shù)據(jù)時(shí),字符串對象是以文字作為一個單位儒溉,而緩存區(qū)對象是以字節(jié)作為一個單位宦焦。比如,針對一個引用了字符串對象的str變量來說顿涣,str2獲取的是第三個文字波闹,而針對一個引用了緩存區(qū)對象的buf對象來說,buf2獲取的是緩存區(qū)中的第三個字節(jié)數(shù)據(jù)轉(zhuǎn)換為整數(shù)后的數(shù)值涛碑。如下:

console.log(str[2]);//隊(duì)
console.log(buf[2]);//135

正確讀取文件內(nèi)容的方式

從上文中可以看出精堕,如果讀取文件內(nèi)容是,恰好不是一個完整文字時(shí)蒲障,可能會輸出錯誤信息

var fs = require('fs');
var rs = fs.createReadStream('testdata.md', {bufferSize: 11});
var data = '';
rs.on("data", function (trunk){
    data += trunk;
});
rs.on("end", function () {
    console.log(data);
});

可能會輸出如下的內(nèi)容

事件循???和請求???象構(gòu)成了Node.js???異步I/O模型的???個基本???素歹篓,這也是典???的消費(fèi)???生產(chǎn)者場景瘫证。 

造成這個問題的根源在于data += trunk語句里隱藏的錯誤,在默認(rèn)的情況下庄撮,trunk是一個Buffer對象背捌。這句話的實(shí)質(zhì)是隱藏了toString的變換的:

data = data.toString() + trunk.toString(); 

由于漢字不是用一個字節(jié)來存儲的,導(dǎo)致有被截破的漢字的存在洞斯,于是出現(xiàn)亂碼载萌。解決這個問題有一個簡單的方案,是設(shè)置編碼集:

var rs = fs.createReadStream('testdata.md', {encoding: 'utf-8', bufferSize: 11});

下面展示一個正確讀取文件巡扇,并連接buffer對象的方法

var buffers = [];
var nread = 0;
readStream.on('data', function (chunk) {
    buffers.push(chunk);
    nread += chunk.length;
});
readStream.on('end', function () {
    var buffer = null;
    switch(buffers.length) {
        case 0: buffer = new Buffer(0);
            break;
        case 1: buffer = buffers[0];
            break;
        default:
            buffer = new Buffer(nread);
            for (var i = 0, pos = 0, l = buffers.length; i < l; i++) {
                var chunk = buffers[i];
                // 把chunk復(fù)制到buffer對象從pos位置開始的地方
                chunk.copy(buffer, pos);
                pos += chunk.length;
            }
        break;
    }
});

buf.copy(targetBuffer,[targetStart],[sourceStart],[sourceEnd]);

在Buffer對象的copy方法中扭仁,使用四個參數(shù),第一個參數(shù)為必須指定的參數(shù)厅翔,其余三個參數(shù)均為可選參數(shù)乖坠。第一個參數(shù)用于指定復(fù)制的目標(biāo)Buffer對象。第二個參數(shù)用于指定目標(biāo)Buffer對象中從第幾個字節(jié)開始寫入數(shù)據(jù)刀闷,參數(shù)值為一個小于目標(biāo)的Buffer對象長度的整數(shù)值熊泵,默認(rèn)值為0(從開始處寫入數(shù)據(jù))。第三個參數(shù)用于指定從復(fù)制源Buffer對象中獲取數(shù)據(jù)時(shí)的開始位置甸昏,默認(rèn)值為0顽分,即從復(fù)制源Buffer對象中的第一個字節(jié)開始獲取數(shù)據(jù),第四個參數(shù)用于指定從復(fù)制源Buffer對象中獲取數(shù)據(jù)時(shí)的結(jié)束位置施蜜,默認(rèn)值為復(fù)制源Buffer對象的長度卒蘸,即一直獲取完畢復(fù)制源Buffer對象中的所有剩余數(shù)據(jù)。

推薦文章

粉絲日志 - nodejs buffer對象
淺析 nodejs buffer 對象

dns

dns.lookup()

根據(jù)域名解析ip地址翻默,設(shè)置參數(shù)可以返回一個域名對應(yīng)的多個IP

var dns = require('dns');

dns.lookup('www.baid.com', {all: true} function(err, address, family){
    console.log(address)
})

[ { address: '122.10.91.48', family: 4 } ]

注意:lookup函數(shù)會受本地host的影響缸沃。如,在host文件中配置了 127.0.0.1 www.baidu.com 使用dns.lookup()查詢www.baidu.com這個域名時(shí)修械,會返回 127.0.0.1趾牧。此時(shí)可以考慮使用dns.resolve4()方法來替代解析域名。

dns.lookupService(address, port, callback)

使用dns.lookupService(address, port, callback)方法肯污,該方法依賴getnameinfo底層函數(shù)翘单。
callback函數(shù)有三個參數(shù)(err, hostname, service),service是protocol,為http或https,使用如下所示:

dns.lookupService('127.0.0.1',80,(err,hostname,service)=>{
    if(err) console.log(err);
    console.log('該IP對應(yīng)的主機(jī)為:'+hostname+' 協(xié)議為:'+service);
});
// 該IP對應(yīng)的主機(jī)為:localhost 協(xié)議為:http

推薦文章

process 模塊

簡介

process是一個全局內(nèi)置對象蹦渣,可以在代碼中的任何位置訪問此對象哄芜,這個對象代表我們的node.js代碼宿主的操作系統(tǒng)進(jìn)程對象。使用process對象可以截獲進(jìn)程的異常剂桥、退出等事件忠烛,也可以獲取進(jìn)程的當(dāng)前目錄属提、環(huán)境變量权逗、內(nèi)存占用等信息美尸,還可以執(zhí)行進(jìn)程退出、工作目錄切換等操作斟薇。

Process模塊提供了訪問正在運(yùn)行的進(jìn)程师坎。child_process模塊可以創(chuàng)建子進(jìn)程,并與他們通信堪滨。cluster模塊提供了實(shí)現(xiàn)共享相同端口的集群服務(wù)能力胯陋,允許多個請求同時(shí)處理。

process實(shí)現(xiàn)了EventEmitter接口袱箱,exit方法會在當(dāng)進(jìn)程退出的時(shí)候執(zhí)行遏乔。因?yàn)檫M(jìn)程退出之后將不再執(zhí)行事件循環(huán),所有只有那些沒有回調(diào)函數(shù)的代碼才會被執(zhí)行发笔。在下面例子中盟萨,setTimeout里面的語句是沒有辦法執(zhí)行到的。

process.on('exit', function () {
  setTimeout(function () {
    console.log('This will not run');
  }, 100);
  console.log('Bye.');
});

屬性

  • process.pid:當(dāng)前進(jìn)程的進(jìn)程號了讨。

  • process.version:Node的版本捻激,比如v0.10.18。

  • process.platform:當(dāng)前系統(tǒng)平臺前计,比如Linux胞谭。

  • process.title:默認(rèn)值為“node”,可以自定義該值男杈。

  • process.argv:當(dāng)前進(jìn)程的命令行參數(shù)數(shù)組丈屹。

      console.log("argv: ",process.argv.slice(2));
      //node test.js a b c
      //argv:  [ 'a', 'b', 'c' ]
    
  • process.env:指向當(dāng)前shell的環(huán)境變量,比如process.env.HOME伶棒。

  • process.execPath:運(yùn)行當(dāng)前進(jìn)程的可執(zhí)行文件的絕對路徑泉瞻。

  • process.memoryUsage():node進(jìn)程內(nèi)存的使用情況,rss代表ram的使用情況苞冯,vsize代表總內(nèi)存的使用大小袖牙,包括ram和swap;

  • process.heapTotal,process.heapUsed:分別代表v8引擎內(nèi)存分配和正在使用的大小舅锄。

  • process.stdout:指向標(biāo)準(zhǔn)輸出鞭达。

  • process.stdin:指向標(biāo)準(zhǔn)輸入。

  • process.stderr:指向標(biāo)準(zhǔn)錯誤皇忿。

方法

  • process.exit():退出當(dāng)前進(jìn)程畴蹭。

  • process.cwd():返回運(yùn)行當(dāng)前腳本的工作目錄的路徑。_

  • process.chdir():改變工作目錄鳍烁。

  • process.nextTick():將一個回調(diào)函數(shù)放在下次事件循環(huán)的頂部叨襟。
    process.nextTick()的例子汇陆,指定下次事件循環(huán)首先運(yùn)行的任務(wù)炼蹦。

      process.nextTick(function () {
          console.log('Next event loop!');
      });
    

    上面代碼可以用setTimeout改寫,但是nextTick回調(diào)的優(yōu)先級更高,會被放在事件隊(duì)列的最前面导梆,而settimeout是放在最后面.

      setTimeout(function () {
         console.log('Next event loop!');
      }, 0)
    

事件

  • exit事件

    當(dāng)前進(jìn)程退出時(shí)腹躁,會觸發(fā)exit事件丹擎,可以對該事件指定回調(diào)函數(shù)砌滞。這一個用來定時(shí)檢查模塊的狀態(tài)的好鉤子(hook)(例如單元測試),當(dāng)主事件循環(huán)在執(zhí)行完’exit’的回調(diào)函數(shù)后將不再執(zhí)行,所以在exit事件中定義的定時(shí)器可能不會被加入事件列表.

      process.on('exit', function () {
          fs.writeFileSync('/tmp/myfile', 'This MUST be saved on exit.');
      });
    
  • uncaughtException事件

在你接觸node之后,你就會發(fā)現(xiàn)那些影響了主事件循環(huán)的異常會把整個node進(jìn)程宕掉的念链。這會是相當(dāng)嚴(yán)重的問題盼忌,所以process提供了另外一個有用的事件uncaughtException來解決這個問題,當(dāng)前進(jìn)程拋出一個沒有被捕捉的意外時(shí)掂墓,會觸發(fā)uncaughtException事件谦纱。

process.on('uncaughtException', function (err) {
  console.log('Caught exception: ' + err);
});
setTimeout(function () {
  console.log('This will still run.');
}, 2000);
// Intentionally cause an exception, but don't catch it.
nonexistentFunc();
console.log('This will not run.');

我們來看上面的例子,我們注冊了uncaughtException事件來捕捉系統(tǒng)異常君编。執(zhí)行到nonexistentFunc()時(shí)服协,因?yàn)樵摵瘮?shù)沒有定義所以會拋出異常。

Caught exception: ReferenceError: nonexistentFunc is not defined
This will still run.

再看一個例子

var http = require('http');
var server = http.createServer(function(req,res) {
  res.writeHead(200, {});
  res.end('response');
  badLoggingCall('sent response');
  console.log('sent response');
});
process.on('uncaughtException', function(e) {
  console.log(e);
});
server.listen(8080);

在這里例子中我們創(chuàng)建了一個web服務(wù)器啦粹,當(dāng)處理完請求之后偿荷,我們會執(zhí)行badLoggingCall()方法。因?yàn)檫@個方法不存在唠椭,所以會有異常拋出跳纳。但是我們注冊的uncaughtException事件會對異常做出處理,這樣服務(wù)器不會受到影響得以繼續(xù)運(yùn)行贪嫂。我們會在服務(wù)器端記錄錯誤日志

[ReferenceError: badLoggingCall is not defined]

但常規(guī)不建議使用該粗略的異常捕獲處理寺庄,建議使用 domains

child process

child_process是Node.js的一個十分重要的模塊,通過它可以實(shí)現(xiàn)創(chuàng)建多進(jìn)程力崇,以利用單機(jī)的多核計(jì)算資源斗塘。雖然,Nodejs天生是單線程單進(jìn)程的亮靴,但是有了child_process模塊馍盟,可以在程序中直接創(chuàng)建子進(jìn)程,并使用主進(jìn)程和子進(jìn)程之間實(shí)現(xiàn)通信茧吊,等到子進(jìn)程運(yùn)行結(jié)束以后贞岭,主進(jìn)程再用回調(diào)函數(shù)讀取子進(jìn)程的運(yùn)行結(jié)果。

推薦文章

domain

nodejs的尷尬

try catch無法捕獲異步中的異常搓侄。所以我們能做的只能是

app.get('/index', function (req, res) {
  // 業(yè)務(wù)邏輯  
});

process.on('uncaughtException', function (err) {
  logger.error(err);
});

這個時(shí)候瞄桨,雖然我們可以記錄下這個錯誤的日志,且進(jìn)程也不會異常退出讶踪,但是我們是沒有辦法對發(fā)現(xiàn)錯誤的請求友好返回的芯侥,只能夠讓它超時(shí)返回。

這個時(shí)候 domain模塊就出現(xiàn)了乳讥,它可以捕捉異步錯誤柱查。而我們?yōu)榱俗?domain 模塊來接管所有的http請求中的異常,所以把它寫成一個中間件是非常方便的廓俭。

app.use(function (req, res, next) {
    var reqDomain = domain.create();
    reqDomain.on('error', function (err) {  // 下面拋出的異常在這里被捕獲,觸發(fā)此事件
        console.log('捕獲到錯誤');
        res.send(500, err.stack);           // 成功給用戶返回了 500
    });
    reqDomain.run(next);
});

app.use(function(req,res,next){ .....}) 這是一個中間件,用來接收所有http請求,這里你可以捕獲requestresponse 對象用來做一些過濾,邏輯判斷等等,最后通過 next 來放行本次請求,那么這個中間件就完成了他的一次使命.

然后我們在 process 上將未處理的異常捕捉一下,做到萬無一失.

process.on('uncaughtException', function (err) {
    console.error("uncaughtException ERROR");
    if (typeof err === 'object') {
        if (err.message) {
            console.error('ERROR: ' + err.message)
        }
        if (err.stack) {
            console.error(err.stack);
        }
    } else {
        console.error('argument is not an object');
    }
});

然后拋出錯誤實(shí)踐一下,是否能被捕捉

app.get('/err', function (req, res) {
    //throw new Error('exception'); 
    setTimeout(function () {
        throw new Error('exception'); // 拋出一個異步異常
    }, 1000);
})

每次 domian 捕獲到錯誤后,我都在控制臺輸出了一行提示信息 "捕獲到錯誤" 當(dāng)前進(jìn)程并沒有因?yàn)楫惓6鴴斓?這就是我們要的效果.

我們之所以想到用 setTimeout 就是想模擬一個異步的回調(diào),如果你直接 throw new Error('exception');這樣就不是異步了,直接會被 process 上的 uncaughtException 來接管.

進(jìn)階文章

cluster

nodejs最大的特點(diǎn)就是單進(jìn)程物赶、無阻塞運(yùn)行白指,并且是異步事件驅(qū)動的留晚。Nodejs的這些特性能夠很好的解決一些問題酵紫,例如在服務(wù)器開發(fā)中,并發(fā)的請求處理是個大問題错维,阻塞式的函數(shù)會導(dǎo)致資源浪費(fèi)和時(shí)間延遲奖地。通過事件注冊、異步函數(shù)赋焕,開發(fā)人員可以提高資源的利用率参歹,性能也會改善。既 然Node.js采用單進(jìn)程隆判、單線程模式犬庇,那么在如今多核硬件流行的環(huán)境中,單核性能出色的Nodejs如何利用多核CPU呢侨嘀?

cluster是一個nodejs內(nèi)置的模塊臭挽,用于nodejs多核處理。cluster模塊咬腕,可以幫助我們簡化多進(jìn)程并行化程序的開發(fā)難度欢峰,輕松構(gòu)建一個用于負(fù)載均衡的集群。

推薦文章

fork其實(shí)就是創(chuàng)建子進(jìn)程的方法涨共,新創(chuàng)建的進(jìn)程被認(rèn)為是子進(jìn)程纽帖,而調(diào)用fork的進(jìn)程則是父進(jìn)程。 子進(jìn)程和父進(jìn)程本來是在獨(dú)立的內(nèi)存空間中的举反。但當(dāng)你使用了fork之后懊直,兩者就處在同一個作用域內(nèi)了。 但是火鼻,內(nèi)存的讀寫吹截,文件的map,都不會影響對方。也就是說凝危,你創(chuàng)建的進(jìn)程其實(shí)可以相互通信波俄,并且被master進(jìn)程 管理。

201603170937192.png-9kB
201603170937192.png-9kB

進(jìn)程間使用消息通知來共享數(shù)據(jù)

多進(jìn)程使用同一端口不沖突的原因

util 模塊

簡介

var util = require("util");

util.inherits(constructor, superConstructor)

util.inherits(constructor, superConstructor)是一個實(shí)現(xiàn)對象間原型繼承的方法蛾默。JavaScript 的面向?qū)ο筇匦允腔谠偷睦^承懦铺,與常見的基于類的不同,JavaScript 沒有提供對象繼承的語言級別特性支鸡,而是通過原型鏈復(fù)制來實(shí)現(xiàn)的冬念。inherits方法可以將父類原型鏈上的方法復(fù)制到子類中趁窃,實(shí)現(xiàn)原型式繼承。

var events = require("events");

//MyStream構(gòu)造函數(shù)急前,在構(gòu)造函數(shù)將this指向本對象
function MyStream() {
    events.EventEmitter.call(this);
}

//復(fù)制父對象上所有的方法
util.inherits(MyStream, events.EventEmitter);

//對MyStream類添加原型方法
MyStream.prototype.write = function(data) {
    this.emit("data", data);
}

var stream = new MyStream();

//由于MyStream繼承自EventEmitter醒陆,所以其實(shí)例stream是MyStream類的實(shí)例也是EventEmitter類的實(shí)例
console.log(stream instanceof events.EventEmitter); // true
console.log(MyStream.super_ === events.EventEmitter); // true

//父類中的方法調(diào)用
stream.on("data", function(data) {
    console.log('Received data: "' + data + '"');
})
//子類中的方法調(diào)用
stream.write("It works!"); // Received data: "It works!"

event 模塊

此模塊是一個核心模塊,直接引用

var events = require('events');

簡介

events模塊只提供了一個對象,events.EventEmitter裆针,核心是 事件發(fā)射 和 事件監(jiān)聽 功能刨摩。每個事件由一個事件名(用于標(biāo)識事件),和多個參數(shù)組成世吨。事件名:字符串澡刹,通常表達(dá)一定的語義;事件被發(fā)射時(shí)耘婚,監(jiān)聽該事件的函數(shù)被依次調(diào)用罢浇。

監(jiān)聽

var events = require("events");
var emitter = new events.EventEmitter();

emitter.on("/click", function () {
    console.log("first event");
})
emitter.on("/click", function () {
    console.log("second event");
})

emitter.emit("/click");

注意

  • /click是事件名(用于標(biāo)識事件)
  • 可以多個監(jiān)聽,用于監(jiān)聽同一個事件沐祷,然后依次執(zhí)行嚷闭;
  • 需要先監(jiān)聽,后發(fā)射赖临;
  • 監(jiān)聽是on胞锰,發(fā)射是emit
  • 把emit發(fā)射的事件賦值給變量。如果有監(jiān)聽該事件的思杯,則變量值為true胜蛉,如果無監(jiān)聽該事件,則返回值為false色乾。注意誊册,該變量賦值后不會改變,即
var nn = emitter.emit("/click1");
emitter.on("/click1", function () {
    console.log("first event");
})
console.log(nn);// false

只監(jiān)聽一次:

EventEmitter.once(事件名, 回調(diào)函數(shù)),即把上面的on替換為once即可,然后這個只監(jiān)聽一次就失效暖璧;

移除事件

EventEmitter.removeListener(事件名, 回調(diào)函數(shù)名)

var events = require("events");
var emitter = new events.EventEmitter();
var first = function () {
    console.log("first event");
}
var second = function () {
    console.log("second event");
}

emitter.on("/click", first)
emitter.on("/click", second)
emitter.emit("/click");
emitter.removeListener("/click", first);
console.log("————移除完成————");
emitter.emit("/click");

輸出
// first event
// second event
// --移除完成--
// second event

全部移除

var events = require("events");
var emitter = new events.EventEmitter();
var first = function () {
    console.log("first event");
}
var second = function () {
    console.log("second event");
}

emitter.on("/click", first)
emitter.on("/click", second)
emitter.emit("/click");
emitter.removeAllListeners("/click");
console.log("————移除完成————");
emitter.emit("/click");

輸出
// first event
// second event
// --移除完成--

error事件

當(dāng)遇見異常時(shí)會發(fā)射error事件案怯,EventEmitter規(guī)定,如果沒有監(jiān)聽其的監(jiān)聽器澎办,Node.js會把其當(dāng)成異常嘲碱,退出程序并打印調(diào)用棧。因此需要設(shè)置監(jiān)聽其的監(jiān)聽器局蚀,避免遇見錯誤后整個程序崩潰麦锯。

var events = require("events");
var emitter = new events.EventEmitter();
var first = function () {
    console.log("first event");
}
var error = function (error) {
    console.log(error);
}

emitter.on("/click", first)
emitter.on("error", error)  //如果沒有這一行代碼,下面在發(fā)射error時(shí)會出錯然后退出程序
emitter.emit("/click");
emitter.emit("error", error)
console.log("————移除完成————");
emitter.emit("/click");

輸出
// first event
// [Function]
// --移除完成--
// first event

實(shí)例

任何類型如果繼承了該類就是一個事件觸發(fā)體,繼承該類的任何類型都是事件的一個實(shí)例(給事件綁定一個函數(shù)后,一旦觸發(fā)事件,馬上執(zhí)行事件綁定函數(shù).

下面例子演示通過繼承給對象綁定一個事件琅绅,來自一介布衣_events模塊的精彩示例

var util = require('util');
var events = require('events');

var Anythin = function (name) {
    this.name = name;
}

util.inherits(Anythin, events.EventEmitter);

//創(chuàng)建一只貓
var cat = new Anythin('黑貓');
//綁定事件
cat.on("activity", function (activity) {
    console.log(this.name + activity);
});

//創(chuàng)建一只老鼠
var mouse = new Anythin('老鼠');
//綁定事件
mouse.on("activity", function (activity) {
    console.log(this.name + activity);
});

//創(chuàng)建屋子的主人
var people = new Anythin('主人');
//綁定事件
people.on("activity", function (activity) {
    console.log(this.name + activity);
});

//創(chuàng)建主人的孩子
var child = new Anythin('嬰兒');
//綁定事件
child.on("activity", function (activity) {
    console.log(this.name + activity);
});

console.log('靜靜的夜晚,主人一家正在酣睡......');
console.log('黑貓緊盯著黑暗的角落.....');

setTimeout(function(){
    console.log('黑貓?jiān)僖矆?jiān)持不住了......');
    cat.emit("activity",'睡著了');
    mouse.emit("activity",'爬出洞口');
    people.emit("activity",'聞聲而起');
    child.emit("activity",'開始哭哭啼啼');
},3000);

上面的例子就是一個萬能的造物主,可以創(chuàng)建宇宙中的萬事萬物.上面創(chuàng)建的一個事件引發(fā)體 "黑貓" 由于晚上'上班' 太辛苦,而偷偷去睡覺,這一事件誘因直接導(dǎo)致囂張的'老鼠'從洞里出來覓食,由于老鼠覓食動作不當(dāng)而吵醒做夢的'主人'及正在酣睡的'嬰兒'
造物主制造的各種角色時(shí)已天生有個綁定事件的活動 activity 扶欣,這個功勞要?dú)w功于:

util.inherits(Anythin, events.EventEmitter);

util 模塊也是node.js 中的核心模塊,他構(gòu)建了一些常用的代碼, inherits 就是其中之一,讓前面的類型繼承后面的的類型.所以上面的代碼是 Anythin 類型繼承了 EventEmitter 類型,所以EventEmitter 類型實(shí)現(xiàn)的方法屬性可以直接使用(當(dāng)然包括綁定事件觸發(fā)函數(shù)的方法,注冊事件的方法 等)

其他系列文章

Nodejs模塊學(xué)習(xí)筆記
極客學(xué)院 nodejs官方文檔

未完待續(xù)~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子料祠,更是在濱河造成了極大的恐慌骆捧,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件髓绽,死亡現(xiàn)場離奇詭異敛苇,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)顺呕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門枫攀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人塘匣,你說我怎么就攤上這事脓豪∠锏郏” “怎么了忌卤?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長楞泼。 經(jīng)常有香客問我驰徊,道長,這世上最難降的妖魔是什么堕阔? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任棍厂,我火速辦了婚禮,結(jié)果婚禮上超陆,老公的妹妹穿的比我還像新娘牺弹。我一直安慰自己,他們只是感情好时呀,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布张漂。 她就那樣靜靜地躺著,像睡著了一般谨娜。 火紅的嫁衣襯著肌膚如雪航攒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天趴梢,我揣著相機(jī)與錄音漠畜,去河邊找鬼。 笑死坞靶,一個胖子當(dāng)著我的面吹牛憔狞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播彰阴,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼瘾敢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起廉丽,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤倦微,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后正压,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體欣福,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年焦履,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拓劝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡嘉裤,死狀恐怖郑临,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情屑宠,我是刑警寧澤厢洞,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站典奉,受9級特大地震影響躺翻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜卫玖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一公你、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧假瞬,春花似錦陕靠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至芦劣,卻和暖如春粗俱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背虚吟。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工寸认, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人串慰。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓偏塞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親邦鲫。 傳聞我的和親對象是個殘疾皇子灸叼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容

  • https://nodejs.org/api/documentation.html 工具模塊 Assert 測試 ...
    KeKeMars閱讀 6,305評論 0 6
  • Node基本 node的最大特性莫過于基于事件驅(qū)動的非阻塞I/O模型神汹。 node通過事件驅(qū)動的方式處理請求,無須為...
    AkaTBS閱讀 2,159評論 0 11
  • Node.js是目前非彻沤瘢火熱的技術(shù)屁魏,但是它的誕生經(jīng)歷卻很奇特。 眾所周知捉腥,在Netscape設(shè)計(jì)出JavaScri...
    w_zhuan閱讀 3,607評論 2 41
  • 內(nèi)容來自《Node.js開發(fā)指南》 核心模塊是 Node.js 的心臟氓拼,它由一些精簡而高效的庫組成,為 Node....
    angelwgh閱讀 888評論 0 1
  • # 模塊機(jī)制 node采用模塊化結(jié)構(gòu)抵碟,按照CommonJS規(guī)范定義和使用模塊桃漾,模塊與文件是一一對應(yīng)關(guān)系,即加載一個...
    RichRand閱讀 2,482評論 0 3