摘要:為指定事件注冊一個監(jiān)聽器,接受一個字符串和一個回調(diào)函數(shù)。發(fā)射事件,傳遞若干可選參數(shù)到事件監(jiān)聽器的參數(shù)表。為指定事件注冊一個單次監(jiān)聽器,即監(jiān)聽器最多只會觸發(fā)一次,觸發(fā)后立刻解除該監(jiān)聽器。
1.Node.js 簡介
Node.js 其實就是借助谷歌的 V8 引擎,將桌面端的 js 帶到了服務器端,它的出現(xiàn)我將其歸結為兩點:
V8 引擎的出色;
js 異步 io 與事件驅動給服務器帶來極高的 吞吐量/硬件性能 比例。
2.安裝和配置Node.js安裝的話基本是分為 Windows 和 POSIX(為*unx 和 Mac等系統(tǒng)的統(tǒng)稱)。
2.1.在 Windows 上,很簡單,訪問官網(wǎng),下載對應的安裝包安裝即可。 2.2.在 POSIX 上安裝大都可以從相應的包管理器上進行安裝(非大神不推薦用源碼,因為源碼編譯涉及相關參數(shù))。
不過包管理器上的并非是最新的,還可能是很老舊的版本,所以需要我們?nèi)ス倬W(wǎng)下載編譯好的二進制來進行安裝.
關于安裝,我在我的其他文章中有說到,比較簡單的.
在安裝的時候,會默認自帶一個 npm 包管理器,這個 npm 上托管了幾乎所有的 node.js 程序包,你能夠通過它下載各種流行的基于 node.js 的軟件.
當然,快速入門少不了 Hello World,Node.js其實和瀏覽器上的 javascript 差不太多,只是Node.js上增加了一些引用的方法以及結構,并且去除了 Dom 的操作(Node上并沒有Dom可以操作..),所以,你可以直接用以下語句打印出一句"Hello World":
console.log("Hello World");3.2.建立一個Web Server
Node.js是一個服務器程序,當然就要提供Web服務,以下代碼能讓你建立起一個最基礎的Web服務器,因為它對所有的請求都只返回同樣的頁面:
//app.js var http = require("http"); http.createServer(function(req, res) { res.writeHead(200, {"Content-Type": "text/html"}); res.write("3.3.異步IONode.js
"); res.end("Hello World
"); }).listen(3000); console.log("HTTP server is listening at port 3000.");
在js 中,最重要的部分之一就是它的異步編程,通過事件輪詢,在單線程上它能夠接受更多的請求并且將資源最大化利用.
比如像下面的讀取文件程序,在調(diào)用讀取函數(shù)后,程序會繼續(xù)往下運行,等到讀取完成后,才會調(diào)用讀取函數(shù)所綁定的那個回調(diào)函數(shù):
//readfilesync.js var fs = require("fs"); var data = fs.readFileSync("file.txt", "utf-8"); console.log(data); console.log("end.");3.4.模塊和包 3.4.1.創(chuàng)建模塊
node的幾乎所有程序都是通過各種模塊以及包組合完成的.每個模塊或者包都有他特殊的功能以及特定的調(diào)用方法.
創(chuàng)建及加載模塊:
// 讓我們以一個例子來了解模塊。創(chuàng)建一個 module.js 的文件,內(nèi)容是: //module.js var name; exports.setName = function(thyName) { name = thyName; }; exports.sayHello = function() { console.log("Hello " + name); }; // 在同一目錄下創(chuàng)建 getmodule.js,內(nèi)容是: //getmodule.js var myModule = require("./module"); myModule.setName("BYVoid"); myModule.sayHello();3.4.2單次加載
在同一個程序中,同一個模塊只會被加載一次,node會通過將模塊的地址進行 hash并存起來,所以不會加載多次.當然這樣的話,你在程序中引用兩次同一個模塊,他們其實是一個.
3.4.3.覆蓋exports模塊通過 exports 暴露相關的方法或者屬性,未通過此方法暴露的方法和屬性是無法被外界訪問到的(和java C++ C# 中的類差不多)
但是,你不能直接通過以下方式來覆蓋export函數(shù),這樣的話不會有任何效果
export = function(){ console.log("Hello"); }
當我們只需要暴露一個方法或屬性的時候,用exports 就略顯復雜,我么可以通過以下方式將 exports 進行覆蓋:
module.exports = function(){ console.log("Hello"); }3.5.創(chuàng)建包
每個包中有很多的模塊,因為之前我們知道,每個模塊最好是多帶帶存放在一個js文件中,那包我們就應該存放在一個文件夾中.并且提供一個外部訪問的接口(通常是一個模塊),用于整體管理及使用這個包的所有功能.
Node.js 在調(diào)用某個包時,會首先檢查包中 package.json 文件的 main 字段,將其作為包的接口模塊,如果 package.json 或 main 字段不存在,會嘗試尋找 index.js 或 index.node 作
為包的接口。
package.json 是 CommonJS 規(guī)定的用來描述包的文件,完全符合規(guī)范的package.json 文件應該含有以下字段。
name:包的名稱,必須是唯一的,由小寫英文字母、數(shù)字和下劃線組成,不能包含
空格。
description:包的簡要說明。
version:符合語義化版本識別①規(guī)范的版本字符串。
keywords:關鍵字數(shù)組,通常用于搜索。
maintainers:維護者數(shù)組,每個元素要包含 name、email (可選)、web (可選)
字段。
contributors:貢獻者數(shù)組,格式與maintainers相同。包的作者應該是貢獻者
數(shù)組的第一個元素。
bugs:提交bug的地址,可以是網(wǎng)址或者電子郵件地址。
licenses:許可證數(shù)組,每個元素要包含 type (許可證的名稱)和 url (鏈接到
許可證文本的地址)字段。
repositories:倉庫托管地址數(shù)組,每個元素要包含 type (倉庫的類型,如 git )、
url (倉庫的地址)和 path (相對于倉庫的路徑,可選)字段。
dependencies:包的依賴,一個關聯(lián)數(shù)組,由包名稱和版本號組成。
下面是一個完全符合 CommonJS 規(guī)范的 package.json 示例:
{ "name": "mypackage", "description": "Sample package for CommonJS. This package demonstrates the required elements of a CommonJS package.", "version": "0.7.0", "keywords": [ "package", "example" ], "maintainers": [ { "name": "Bill Smith", "email": "bills@example.com", } ], "contributors": [ { "name": "BYVoid", "web": "http://www.byvoid.com/" } ], "bugs": { "mail": "dev@example.com", "web": "http://www.example.com/bugs" }, "licenses": [ { "type": "GPLv2", "url": "http://www.example.org/licenses/gpl.html" } ], "repositories": [ { "type": "git", "url": "http://github.com/BYVoid/mypackage.git" } ], "dependencies": { "webkit": "1.2", "ssl": { "gnutls": ["1.0", "2.0"], "openssl": "0.9.8" } } }3.6 Node.js包管理器
通過使用Node.js的包管理器,你可以下載到幾乎所有的js包.
獲取一個包如下
npm install express
以上代碼將會將express安裝到當前項目的文件中
如果要將其安裝在全局(當前電腦一次安裝,所有地方都可以使用),可以在參數(shù)中加入 -g,如果是要將其加入項目依賴,可以加入以下參數(shù) --save-dev,這樣node會自動將當前包的信息寫入到項目的 package.json 中.
這個略過,并不打算發(fā)布,等需要時看也不遲
3.8.調(diào)試 3.8.1.命令行調(diào)試調(diào)試其實方法很多,可以直接在命令行中進行單步調(diào)試,以下是nodejs支持的調(diào)試命令:
命令 | 功能 |
---|---|
run | 執(zhí)行腳本,在第一行暫停 |
restart | 重新執(zhí)行腳本 |
cont, c | 繼續(xù)執(zhí)行,直到遇到下一個斷點 |
next, n | 單步執(zhí)行 |
step, s | 單步執(zhí)行并進入函數(shù) |
out, o | 從函數(shù)中步出 |
setBreakpoint(), sb() | 在當前行設置斷點 |
setBreakpoint(‘f()’), sb(...) | 在函數(shù)f的第一行設置斷點 |
setBreakpoint(‘script.js’, 20), sb(...) | 在 script.js 的第20行設置斷點 |
clearBreakpoint, cb(...) | 清除所有斷點 |
backtrace, bt | 顯示當前的調(diào)用棧 |
list(5) | 顯示當前執(zhí)行到的前后5行代碼 |
watch(expr) | 把表達式 expr 加入監(jiān)視列表 |
unwatch(expr) | 把表達式 expr 從監(jiān)視列表移除 |
watchers | 顯示監(jiān)視列表中所有的表達式和值 |
repl | 在當前上下文打開即時求值環(huán)境 |
kill | 終止當前執(zhí)行的腳本 |
scripts | 顯示當前已加載的所有腳本 |
version | 顯示 V8 的版本 |
這個程序非常好用,雖然我沒有用過,但是看上去很像谷歌瀏覽器的調(diào)試,以后需要時可以試試看.
4.Node.js核心模塊 4.1.全局對象在Node中,有一個類似在瀏覽器中的window一樣的全局對象,叫做 global. console,process等都是其子.
如何定義全局對象就很簡單了:直接綁定在global上的,定義在最外層的,還有沒有使用var聲明的都是全局對象.
4.1.1.process對象這個對象存儲了與當前運行環(huán)境相關的很多信息,并且也是標準輸入輸出的最底層接口,我們在調(diào)用console.log()時,其背后也是通過process來實現(xiàn)的.
其含有以下幾個對象
process.argv 包含當前環(huán)境數(shù)據(jù)
process.stdout 標準輸出接口
process.stdin 標準輸入接口
process.nextTick(callback)的功能是為事件循環(huán)設置一項任務,Node.js 會在
下次事件循環(huán)調(diào)響應時調(diào)用 callback。這個可以用在將兩個大型的耗時操作進行拆散.
4.1.2.console對象這個對象是和我們打交道最多的對象,其含有以下方法:
console.log() 向標準輸出接口打印字符,其有多個參數(shù),當只有一個參數(shù)時,會將當前參數(shù)轉換為字符串并打印出來.
console.error()這個和剛才的log很相似,只不過這個是標準錯誤輸出,也是就是制造一個bug!!!!
console.trace() 向標準錯誤輸出流輸出當前調(diào)用棧
4.2 常用工具util 4.2.1 util.inherits這個方法提供了一個方便的途徑讓我們進行繼承操作,用法如下
util.inherits(constructor, superConstructor)
將兩個對象進行繼承操作
注意,此處繼承只會繼承原型中定義的屬性和方法!!并且 console.log() 并不會打印出原型中的屬性或者方法.
4.2.2.util.inspectutil.inspect(object,[showHidden],[depth],[colors]) 是一個將任一對象轉換為字符串的方法.它不會調(diào)用對象的 toString 方法.
除了以上我們介紹的幾個函數(shù)之外, util還提供了util.isArray()、 util.isRegExp()、
util.isDate()、util.isError() 四個類型測試工具,以及 util.format()、util.debug() 等工具。
events 是 node最重要的模塊.因為node整個運行就是基于事件輪詢的.
4.3.1.事件發(fā)生器events只提供了一個對象: events.EventEmitter.這個對象的核心就是封裝事件功能.下面的代碼向我們演示了這個過程:
var events = require("events"); var emitter = new events.EventEmitter(); emitter.on("someEvent", function(arg1, arg2) { console.log("listener1", arg1, arg2); }); emitter.on("someEvent", function(arg1, arg2) { console.log("listener2", arg1, arg2); }); emitter.emit("someEvent", "byvoid", 1991);
這就是EventEmitter最簡單的用法。接下來我們介紹一下EventEmitter常用的API。
EventEmitter.on(event, listener) 為指定事件注冊一個監(jiān)聽器,接受一個字
符串 event 和一個回調(diào)函數(shù) listener。
EventEmitter.emit(event, [arg1], [arg2], [...]) 發(fā)射 event 事件,傳
遞若干可選參數(shù)到事件監(jiān)聽器的參數(shù)表。
EventEmitter.once(event, listener) 為指定事件注冊一個單次監(jiān)聽器,即
監(jiān)聽器最多只會觸發(fā)一次,觸發(fā)后立刻解除該監(jiān)聽器。
EventEmitter.removeListener(event, listener) 移除指定事件的某個監(jiān)聽
器,listener 必須是該事件已經(jīng)注冊過的監(jiān)聽器。
EventEmitter.removeAllListeners([event]) 移除所有事件的所有監(jiān)聽器,
如果指定 event,則移除指定事件的所有監(jiān)聽器。
4.3.2. error事件EventEmitter定義了一個特殊的叫 error 的事件.當error被觸發(fā)時,如果沒有定義的響應監(jiān)聽器,則會退出程序并打印調(diào)用棧.
所以我們要發(fā)射 error 時,必須要為其設置相應的監(jiān)聽器,來捕獲并處理錯誤,這樣才不會導致程序掛掉.
4.3.3.繼承EventEmitter一般情況下,我們不會直接用到這個對象,而是在繼承中使用它.包括fs,http等都是這樣的操作.
為什么要這樣做呢?原因有兩點。首先,具有某個實體功能的對象實現(xiàn)事件符合語義,
事件的監(jiān)聽和發(fā)射應該是一個對象的方法。其次 JavaScript 的對象機制是基于原型的,支持部分多重繼承,繼承 EventEmitter 不會打亂對象原有的繼承關系。
fs 模塊是文件操作的封裝,它提供了文件的讀取、寫入、更名、刪除、遍歷目錄、鏈接等 POSIX 文件系統(tǒng)操作。與其他模塊不同的是,fs 模塊中所有的操作都提供了異步的和同步的兩個版本,例如讀取文件內(nèi)容的函數(shù)有異步的 fs.readFile() 和同步的 fs.readFileSync()。我們以幾個函數(shù)為代表,介紹 fs 常用的功能,并列出 fs 所有函數(shù)的定義和功能。
4.4.1fs.readFile這個函數(shù)能夠讀取文件中的內(nèi)容,其用法為:
fs.readFile(filename,[encoding],[callback(err,data)])
以下是調(diào)用示例:
var fs = require("fs"); fs.readFile("content.txt", "utf-8", function(err, data) { if (err) { console.error(err); } else { console.log(data); } });4.4.2.fs.readFileSync
fs.readFileSync(filename, [encoding])是 fs.readFile 同步的版本。它接受的參數(shù)和 fs.readFile 相同,而讀取到的文件內(nèi)容會以函數(shù)返回值的形式返回。如果有錯誤發(fā)生,fs 將會拋出異常,你需要使用 try 和 catch 捕捉并處理異常。
4.4.3.fs.openfs.open(path, flags, [mode], [callback(err, fd)])是 POSIX open 函數(shù)的封裝,與 C 語言標準庫中的 fopen 函數(shù)類似。它接受兩個必選參數(shù),path 為文件的路徑,flags 可以是以下值:
r :以讀取模式打開文件。
r+ :以讀寫模式打開文件。
w :以寫入模式打開文件,如果文件不存在則創(chuàng)建。
w+ :以讀寫模式打開文件,如果文件不存在則創(chuàng)建。
a :以追加模式打開文件,如果文件不存在則創(chuàng)建。
a+ :以讀取追加模式打開文件,如果文件不存在則創(chuàng)建。
mode 參數(shù)用于創(chuàng)建文件時給文件指定權限,默認是 0666。回調(diào)函數(shù)將會傳遞一個文
件描述符 fd。
fs.read(fd, buffer, offset, length, position, [callback(err, bytesRead, buffer)])是 POSIX read 函數(shù)的封裝,相比 fs.readFile 提供了更底層的接口。
以下是其示例:
var fs = require("fs"); fs.open("content.txt", "r", function(err, fd) { if (err) { console.error(err); return; } var buf = new Buffer(8); fs.read(fd, buf, 0, 8, null, function(err, bytesRead, buffer) { if (err) { console.error(err); return; } console.log("bytesRead: " + bytesRead); console.log(buffer); }) });
當然,fs中的函數(shù)是很多的,如果需要,可以去網(wǎng)上進行更詳細的查閱.
4.5 HTTP 服務器與客戶端其實在node中就已經(jīng)封裝了一個很底層的http模塊,http.Server,幾乎所有的網(wǎng)絡工作都能通過它來完成.
4.5.1 HTTP服務器以下代碼
//app.js var http = require("http"); http.createServer(function(req, res) { res.writeHead(200, {"Content-Type": "text/html"}); res.write("Node.js
"); res.end("Hello World
"); }).listen(3000); console.log("HTTP server is listening at port 3000.");
會建立一個在3000端口監(jiān)聽的程序
4.5.2 GET 請求//httpserverrequestget.js var http = require("http"); var url = require("url"); var util = require("util"); http.createServer(function(req, res) { res.writeHead(200, {"Content-Type": "text/plain"}); res.end(util.inspect(url.parse(req.url, true))); }).listen(3000);4.5.3 POST 請求
//httpserverrequestpost.js var http = require("http"); var querystring = require("querystring"); var util = require("util"); http.createServer(function(req, res) { var post = ""; req.on("data", function(chunk) { post += chunk; }); req.on("end", function() { post = querystring.parse(post); res.end(util.inspect(post)); }); }).listen(3000);4.5.4 http.serverResponse
服務器不僅要接收數(shù)據(jù),也要返回相應的數(shù)據(jù)給客戶端:
http.ServerResponse 是返回給客戶端的信息,決定了用戶最終能看到的結果。它
也是由 http.Server 的 request 事件發(fā)送的,作為第二個參數(shù)傳遞,一般簡稱為
response 或 res。
http.ServerResponse 有三個重要的成員函數(shù),用于返回響應頭、響應內(nèi)容以及結束
請求。
response.writeHead(statusCode, [headers]):向請求的客戶端發(fā)送響應頭。statusCode 是 HTTP 狀態(tài)碼,如 200 (請求成功)、404 (未找到)等。headers 是一個類似關聯(lián)數(shù)組的對象,表示響應頭的每個屬性。該函數(shù)在一個請求內(nèi)最多只能調(diào)用一次,如果不調(diào)用,則會自動生成一個響應頭。
response.write(data, [encoding]):向請求的客戶端發(fā)送響應內(nèi)容。data 是一個 Buffer 或字符串,表示要發(fā)送的內(nèi)容。如果 data 是字符串,那么需要指定
encoding 來說明它的編碼方式,默認是 utf-8。在 response.end 調(diào)用之前,
response.write 可以被多次調(diào)用。
response.end([data], [encoding]):結束響應,告知客戶端所有發(fā)送已經(jīng)完
成。當所有要返回的內(nèi)容發(fā)送完畢的時候,該函數(shù) 必須 被調(diào)用一次。它接受兩個可
選參數(shù),意義和 response.write 相同。如果不調(diào)用該函數(shù),客戶端將永遠處于等待狀態(tài)。
當然,node還能充當一個http的客戶端程序來使用 http 模塊提供了兩個函數(shù) http.request 和 http.get,功能是作為客戶端向 HTTP服務器發(fā)起請求。
4.5.5.1 http.requesthttp.request(options, callback) 發(fā)起 HTTP 請求。接受兩個參數(shù), option 是一個類似關聯(lián)數(shù)組的對象,表示請求的參數(shù), callback是請求的回調(diào)函數(shù)。 option常用的參數(shù)如下所示。
host :請求網(wǎng)站的域名或 IP 地址。
port :請求網(wǎng)站的端口,默認 80。
method :請求方法,默認是 GET。
path :請求的相對于根的路徑,默認是“/”。QueryString 應該包含在其中。例如 /search?query=byvoid。
headers :一個關聯(lián)數(shù)組對象,為請求頭的內(nèi)容。
callback 傳遞一個參數(shù),為 http.ClientResponse 的實例。
http.request 返回一個 http.ClientRequest 的實例。
下面是一個通過 http.request 發(fā)送 POST 請求的代碼:
//httprequest.js var http = require("http"); var querystring = require("querystring"); var contents = querystring.stringify({ name: "byvoid", email: "byvoid@byvoid.com", address: "Zijing 2#, Tsinghua University", }); var options = { host: "www.byvoid.com", path: "/application/node/post.php", method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", "Content-Length" : contents.length } }; var req = http.request(options, function(res) { res.setEncoding("utf8"); res.on("data", function (data) { console.log(data); }); }); req.write(contents); req.end();4.5.5.2 http.get
http.get(options, callback) http 模塊還提供了一個更加簡便的方法用于處
理GET請求: http.get。它是 http.request 的簡化版,唯一的區(qū)別在于http.get
自動將請求方法設為了 GET 請求,同時不需要手動調(diào)用 req.end()。
//httpget.js var http = require("http"); http.get({host: "www.byvoid.com"}, function(res) { res.setEncoding("utf8"); res.on("data", function (data) { console.log(data); }); });
post 和 get 返回的數(shù)據(jù)皆為 http.ClientRequest 對象.其也提供了write和end函數(shù),使用如下:
//httpresponse.js var http = require("http"); var req = http.get({host: "www.byvoid.com"}); req.on("response", function(res) { res.setEncoding("utf8"); res.on("data", function (data) { console.log(data); }); });
其還提供了以下函數(shù):
request.abort():終止正在發(fā)送的請求。
request.setTimeout(timeout, [callback]):設置請求超時時間,timeout 為毫秒數(shù)。當請求超時以后,callback 將會被調(diào)用。
此外還有 request.setNoDelay([noDelay])、request.setSocketKeepAlive
([enable], [initialDelay]) 等函數(shù)。
同時也有 http.ClientResponse,其與 http:ServerResponse相似,提供... data,end和close,分別在數(shù)據(jù)到達,傳輸結束和鏈接結束時觸發(fā),其中 data 事件傳遞一個參數(shù) chunk,表示接收到的數(shù)據(jù).
http.ClientResponse 還提供了以下幾個特殊的函數(shù)。
response.setEncoding([encoding]):設置默認的編碼,當 data 事件被觸發(fā)
時,數(shù)據(jù)將會以 encoding 編碼。默認值是 null,即不編碼,以 Buffer 的形式存
儲。常用編碼為 utf8。
response.pause():暫停接收數(shù)據(jù)和發(fā)送事件,方便實現(xiàn)下載功能。
response.resume():從暫停的狀態(tài)中恢復。
5. 使用Node.js進行Web開發(fā) 5.1 使用Express 框架進行開發(fā)安裝npm install -g express
5.2 建立工程express -t ejs XXXX
接下來的 Nodejs 博客搭建暫未記錄,因為涉及到的知識點較多,需要的話最好還是重新讀一次.
6. Node.js 進階 6.1 模塊加載機制在node中,共有兩種類型的模塊:核心模塊,文件模塊.核心模塊是由node自帶的一些基礎模塊,具有最高的加載優(yōu)先級,文件模塊則是我們自己創(chuàng)建的或者引用的三方模塊.
6.1.1 按路徑查找如果指定了加載路徑,則有以下兩種查找情況
當未指定模塊名稱,而只是制定了文件夾時,node會自動去制定目錄尋找index文件,而index文件的文件類型,按加載順序則有三種:js,json,node.如果這三種類型的index文件都沒有找到,則報錯.
當指定了文件名稱,但是未指定文件后綴時,node也是按照以上的順序進行查找:js,json,node.
6.1.2 通過查找node_modules當我們沒有指定路徑時,node會在node_moudule目錄中去查找,有趣的是,在這里有一個很大的性能問題:
比如你在/home/aiello/develop/foot.js中使用require("bar.js"),node會在當前目錄的node_modules文件夾中尋找該模塊,如果未找到,則會重新往上一級查找,于是node到/home/aiello/develop這級目錄進行查找,如果還沒有它會繼續(xù)往上進行查找,知道找到根目錄,發(fā)現(xiàn)沒有,于是報錯.
能明顯看出來,node在模塊的查找中非常的費時,所以我們應當將模塊放到距離當前應用最近的目錄,并且最好是指定模塊路徑.
6.2 控制流在循環(huán)中使用異步方法,將會遇到
//forloop.js var fs = require("fs"); var files = ["a.txt", "b.txt", "c.txt"]; for (var i = 0; i < files.length; i++) { fs.readFile(files[i], "utf-8", function(err, contents) { console.log(files[i] + ": " + contents); }); }
這是由于回調(diào)函數(shù)太慢了,早都循環(huán)完了,才會調(diào)用到回調(diào)函數(shù),所以最后回調(diào)函數(shù)中的i都是等于循環(huán)結束時的i(不一定),所以會有相關問題,以下代碼將其做一個閉包封裝,以達到理想效果:
//forloopclosure.js var fs = require("fs"); var files = ["a.txt", "b.txt", "c.txt"]; for (var i = 0; i < files.length; i++) { (function(i) { fs.readFile(files[i], "utf-8", function(err, contents) { console.log(files[i] + ": " + contents); }); })(i); }6.3 Node.js 應用部署
普通 Node.js 應用存在以下問題:
不支持故障恢復
沒有日志
無法利用多核提高性能
獨占端口
需要手動啟動
6.3.1 日志功能這個簡單,不做概述
6.3.2 故障恢復使用cluster模塊,可以實現(xiàn)多進程以及主進程與工作進程的結構.
6.3.3 自動啟動制作一個啟動腳本即可
6.3.4 共享端口虛擬主機即可
6.4 Node 不是銀彈so,這個我知道,他不適合做
計算密集型
單用戶多任務
邏輯復雜的事務
Unicode與國際化
起始位置
PDF 154
頁碼 148
起始位置:
PDF 173
頁碼 168
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/92433.html
摘要:原文地址一個非常適合入門學習的博客項目前端掘金一個非常適合入門學習的項目,代碼清晰結構合理新聞前端掘金介紹一個由編寫的新聞。深入淺出讀書筆記知乎專欄前端專欄前端掘金去年的一篇老文章,恰好今天專欄開通,遷移過來。 破解前端面試(80% 應聘者不及格系列):從閉包說起 - 掘金修訂說明:發(fā)布《80% 應聘者都不及格的 JS 面試題》之后,全網(wǎng)閱讀量超過 6W,在知乎、掘金、cnodejs ...
摘要:原文地址一個非常適合入門學習的博客項目前端掘金一個非常適合入門學習的項目,代碼清晰結構合理新聞前端掘金介紹一個由編寫的新聞。深入淺出讀書筆記知乎專欄前端專欄前端掘金去年的一篇老文章,恰好今天專欄開通,遷移過來。 破解前端面試(80% 應聘者不及格系列):從閉包說起 - 掘金修訂說明:發(fā)布《80% 應聘者都不及格的 JS 面試題》之后,全網(wǎng)閱讀量超過 6W,在知乎、掘金、cnodejs ...
摘要:前端日報精選讀書思考一的計算屬性使用開發(fā)調(diào)試開發(fā)者控制臺中,你可能意想不到的功能中字符串轉數(shù)字的陷阱和示例中文設計模式單例模式個人文章設計模式工廠模式個人文章讀書思考二掘金網(wǎng)絡基礎三傳輸層的筆記學習筆記中的屬性學習 2017-10-08 前端日報 精選 Node.js Design Patterns - Second Edition讀書思考(一)Vue的計算屬性_Vue使用typesc...
摘要:阮一峰老師開源作品。書上的示例代碼可以通過在線網(wǎng)站代碼調(diào)試工具調(diào)試。 阮一峰老師開源作品。 書上的示例代碼可以通過 在線網(wǎng)站代碼調(diào)試工具 JS Bin 調(diào)試。 作用域 作用域鏈 每個變量或函數(shù)通過執(zhí)行環(huán)境 (execution context) 定義了其有權訪問的其他數(shù)據(jù),決定了他們各自的行為; 全局執(zhí)行環(huán)境是最頂層的執(zhí)行環(huán)境,根據(jù)宿主環(huán)境的不同,表示全局執(zhí)行環(huán)境的對象也不同:在瀏覽...
摘要:所以經(jīng)常會在一個源碼中看到寫法吧立即執(zhí)行函數(shù)創(chuàng)建變量,保存全局根變量。 // ================立即執(zhí)行函數(shù)================ // 使用(function(){}())立即執(zhí)行函數(shù),減少全局變量 // ----????----函數(shù)聲明 function (){} 與函數(shù)表達式 var funName = function(){}----????---- /...
閱讀 889·2021-11-15 11:38
閱讀 2523·2021-09-08 09:45
閱讀 2823·2021-09-04 16:48
閱讀 2572·2019-08-30 15:54
閱讀 939·2019-08-30 13:57
閱讀 1627·2019-08-29 15:39
閱讀 504·2019-08-29 12:46
閱讀 3529·2019-08-26 13:39