Node.js開發(fā)者必須了解的4個(gè)JS要點(diǎn)
本文為開發(fā)者總結(jié)了4個(gè)Node.js要點(diǎn)。
1. 非阻塞(Non-blocking)或異步I/O
由于Node.js一個(gè)服務(wù)器端框架,所以它主要工作之一是處理瀏覽器請(qǐng)求。在傳統(tǒng)的I/O系統(tǒng)中,每個(gè)請(qǐng)求的發(fā)出都是在上一請(qǐng)求到達(dá)之后才發(fā)出的。所以這被稱為阻塞(blocking)I/O。服務(wù)器會(huì)阻擋其它的請(qǐng)求以處理當(dāng)前請(qǐng)求,從而導(dǎo)致瀏覽器等待。
Node.js不以這種方式來進(jìn)行I/O處理。如果一個(gè)請(qǐng)求需要長時(shí)間處理,Node.js會(huì)把該請(qǐng)求發(fā)送給一個(gè)事件循環(huán)(event loop),然后繼續(xù)處理在調(diào)用堆棧(call stack)中的下一請(qǐng)求。當(dāng)延后請(qǐng)求處理完畢時(shí),它會(huì)告知Node.js同時(shí)瀏覽器會(huì)做出響應(yīng)反饋。
以下使用一個(gè)事例來說明。
Blocking I/O
// take order for table 1 and wait... var order1 = orderBlocking(['Coke', 'Iced Tea']); // once order is ready, take order back to table. serveOrder(order1); // once order is delivered, move on to another table. // take order for table 2 and wait... var order2 = orderBlocking(['Coke', 'Water']); // once order is ready, take order back to table. serveOrder(order2); // once order is delivered, move on to another table. // take order for table 3 and wait... var order3 = orderBlocking(['Iced Tea', 'Water']); // once order is ready, take order back to table. serveOrder(order3); // once order is delivered, move on to another table.
在這個(gè)餐館例子中,服務(wù)員接收了菜單指令,等待飯菜處理,然后在飯菜處理完成后把飯菜端到桌子上。在服務(wù)員等候飯菜處理期間,他會(huì)拒絕其它客人的菜單指令。
Non-blocking I/O
// take order for table 1 and move on...
orderNonBlocking(['Coke', 'Iced Tea'], function(drinks){
return serveOrder(drinks);
});
// take order for table 2 and move on...
orderNonBlocking(['Beer', 'Whiskey'], function(drinks){
return serveOrder(drinks);
});
// take order for table 3 and move on...
orderNonBlocking(['Hamburger', 'Pizza'], function(food){
return serveOrder(food);
});
而在非阻塞模式下,服務(wù)員會(huì)告知廚師他接受到的菜單指令,然后去接收下一桌的指令。當(dāng)?shù)谝蛔里埐颂幚硗戤厱r(shí),他會(huì)為那桌客人上菜,然后繼續(xù)接收其它客人的指令。這樣一來服務(wù)員不會(huì)由于阻塞指令而造成時(shí)間浪費(fèi)。
2. 原型(Prototype)
原型在JS中是一個(gè)復(fù)雜的概念。在典型繼承機(jī)制語言如Java或C++中,為了實(shí)現(xiàn)代碼復(fù)用,你必須先創(chuàng)建一個(gè)類然后透過它來生成對(duì)象或透過類擴(kuò)展來生成對(duì)象。但是在JS中沒有類似的類概念。在JS中創(chuàng)建一個(gè)對(duì)象后,你需要透過它來擴(kuò)展對(duì)象或創(chuàng)建新對(duì)象。這就叫做原型繼承(prototypal inheritence)。
每個(gè)JS對(duì)象都連接著一個(gè)原型對(duì)象并對(duì)并繼承該對(duì)象的屬性。每個(gè)對(duì)象與預(yù)定義JS的Object.prototype相聯(lián)系。如果你透過obj.propName或obj[‘propName'>方式來查找對(duì)象屬性但查找失敗時(shí),這時(shí)可嘗試通過obj.hasOwnProperty(‘propName')的方式進(jìn)行查找,JS運(yùn)行時(shí)會(huì)在在原型對(duì)象中查找屬性。如果屬性不存在于原型鏈中,那么將返回undefined值。
讓我們用以下例子來進(jìn)行說明:
if (typeof Object.create !== 'function') {
Object.create = function (o) {
var F = function () {};
F.prototype = o;
return new F();
};
var otherPerson = Object.create(person);
當(dāng)你創(chuàng)建了一個(gè)新對(duì)象,你必須選定一個(gè)以原型為基礎(chǔ)的對(duì)象。在這里,我們?yōu)閷?duì)象函數(shù)添加了一個(gè)create方法。create方法創(chuàng)建了一個(gè)以其它對(duì)象為原型的對(duì)象,并作為參數(shù)傳入。
當(dāng)我們變更新的對(duì)象時(shí),它的原型是保持不變的。但是,當(dāng)我們改動(dòng)了原型對(duì)象,該變更會(huì)影響所有基于該原型的對(duì)象。
3. 組件(Modules)
如果你曾在Java中使用過包,那么Node.js的組件與之類似。如果沒有,也不用擔(dān)心;組件其實(shí)是簡單的JS文件,用于實(shí)現(xiàn)特定的功能。組件模式的意義是讓你工作得更加輕松。要使用組件,你必須像在JAVA中導(dǎo)入包一樣進(jìn)行JS文件導(dǎo)入。Node.js中有兩種組件
核心組件(Core Modules)- 核心組件是結(jié)合Node.js庫被預(yù)編譯的。其目的是把程序員經(jīng)常使用的功能開放出來,避免重復(fù)勞動(dòng)。常見的核心組件有HTTP, URL, EVENTS, FILE SYSTEM等等。
用戶自定義組件(UserDefined Modules)- 用戶自定義組件是提供給用戶使用以實(shí)現(xiàn)具體功能的組件。當(dāng)核心組件不足以滿足程序員需要的時(shí)候,自定義組件就可派上用場了。
組件是通過require函數(shù)被抽取的。如果這是一個(gè)核心組件,那么參數(shù)就是組件名。如果這是一個(gè)用戶自定義組件,那么參數(shù)就是其在文件系統(tǒng)中的組件路徑。例如:
// extract a core module like this
var http = require('http);
// extract a user defined module like this
var something = require('./folder1/folder2/folder3/something.js');
4. 回調(diào)(Callbacks)
在JS中,函數(shù)是第一類對(duì)象。也就是說你可以像對(duì)常規(guī)對(duì)象那樣對(duì)函數(shù)進(jìn)行所有操作。例如指派函數(shù)到一個(gè)變量,把這些作為參數(shù)傳給方法,把它們聲明為對(duì)象的屬性,甚至是把它們從函數(shù)里返回。
回調(diào)在JS中是異步函數(shù),可以作為參數(shù)傳遞給其它函數(shù)或從其它函數(shù)里執(zhí)行或返回而后再執(zhí)行。這是回調(diào)的基本概念。
當(dāng)我們把一個(gè)回調(diào)函數(shù)作為參數(shù)傳遞給另外的函數(shù)時(shí),我們傳遞的僅僅是函數(shù)的定義;換言之,我們不會(huì)知道回調(diào)函數(shù)的執(zhí)行時(shí)間。這完全依賴于回調(diào)函數(shù)機(jī)制。它會(huì)在稍后某個(gè)時(shí)間點(diǎn)進(jìn)行回調(diào)調(diào)用。這是Node.js的非阻塞或異步行為的基本概念,可用下例進(jìn)行說明:
setTimeout(function() {
console.log("world");
}, 2000)
console.log("hello");
這是一個(gè)最簡單的調(diào)用。我們把一個(gè)匿名函數(shù)作為參數(shù)進(jìn)行傳遞,作用是為setTimeout函數(shù)進(jìn)行控制臺(tái)的輸出記錄登記。因?yàn)檫@僅僅是個(gè)函數(shù)定義,我們不知道函數(shù)何時(shí)會(huì)被執(zhí)行。這取決于setTimeout函數(shù)的second參數(shù),即2S后。
首先,second記錄語句記錄了對(duì)控制臺(tái)的輸出,2S后,在回調(diào)函數(shù)中的記錄語句記錄了輸出的內(nèi)容。
// output hello world
寫在最后
以上4點(diǎn)對(duì)Node.js開發(fā)者來說是要徹底理解和掌握的,建議多動(dòng)手來好好體會(huì)這4個(gè)要點(diǎn)的含義。
- 調(diào)試Node.JS的輔助工具(NodeWatcher)
- node.js開發(fā)中使用Node Supervisor實(shí)現(xiàn)監(jiān)測文件修改并自動(dòng)重啟應(yīng)用
- 我用的一些Node.js開發(fā)工具、開發(fā)包、框架等總結(jié)
- Windows8下搭建Node.js開發(fā)環(huán)境教程
- 在Linux系統(tǒng)中搭建Node.js開發(fā)環(huán)境的簡單步驟講解
- windows8.1+iis8.5下安裝node.js開發(fā)環(huán)境
- 詳解Windows下運(yùn)用Docker部署Node.js開發(fā)環(huán)境
- Node.js開發(fā)之訪問Redis數(shù)據(jù)庫教程
- Node.js開發(fā)指南中的簡單實(shí)例(mysql版)
- Ubuntu 16.04 64位中搭建Node.js開發(fā)環(huán)境教程
- Node.js開發(fā)第三方微信公眾平臺(tái)
- 詳解Node.js開發(fā)中的express-session
- linux環(huán)境安裝node.js開發(fā)環(huán)境搭建圖文教程
- Node.js開發(fā)教程之基于OnceIO框架實(shí)現(xiàn)文件上傳和驗(yàn)證功能
- 如何利用node.js開發(fā)一個(gè)生成逐幀動(dòng)畫的小工具
- Node.js開發(fā)之套接字(socket)編程入門示例
- node.js開發(fā)輔助工具nodemon安裝與配置詳解
相關(guān)文章
nodejs使用Sequelize框架操作數(shù)據(jù)庫的實(shí)現(xiàn)
這篇文章主要介紹了nodejs使用Sequelize框架操作數(shù)據(jù)庫的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
NodeJS整合銀聯(lián)網(wǎng)關(guān)支付(DEMO)
這篇文章主要介紹了NodeJS整合銀聯(lián)網(wǎng)關(guān)支付DEMO的相關(guān)資料非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11
Node.js服務(wù)器環(huán)境下使用Mock.js攔截AJAX請(qǐng)求的教程
Mock.js這個(gè)JavaScript庫最常見的用法便是被用來攔截AJAX請(qǐng)求,well,這里我們就來看一下Node.js服務(wù)器環(huán)境下使用Mock.js攔截AJAX請(qǐng)求的教程:2016-05-05
Node.js實(shí)現(xiàn)爬取網(wǎng)站圖片的示例代碼
本文將利用Node.js開發(fā)一個(gè)小示例—爬取某圖片網(wǎng)站的圖片,文中涉及的知識(shí)點(diǎn)有https模塊、cheerio模塊、fs模塊和閉包,感興趣的可以了解一下2022-04-04
nodejs socket服務(wù)端和客戶端簡單通信功能
這篇文章主要為大家詳細(xì)介紹了nodejs socket服務(wù)端和客戶端簡單通信功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09
Node.js使用NodeMailer發(fā)送郵件實(shí)例代碼
本篇文章主要介紹了Node.js使用NodeMailer發(fā)送郵件實(shí)例代碼,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-03-03
NodeJS落地WebSocket實(shí)踐前端架構(gòu)師破局技術(shù)
這篇文章主要為大家介紹了NodeJS落地WebSocket實(shí)踐前端架構(gòu)師破局技術(shù),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06

