在講NodeJS之前综苔,我們先來說一下終端、客戶端以及服務(wù)端的概念
終端
終端也稱為終端設(shè)備,字面意思也可以理解為結(jié)束的一端或者最終的一端,比如鍵盤、打印機(jī)或者我們的電腦惕澎,也就是用來安裝客戶端等軟件的一個(gè)顯示設(shè)備或者操作設(shè)備。
客戶端
與服務(wù)端對(duì)應(yīng)颜骤,又稱為用戶端唧喉,就是為用戶提供本地服務(wù)的程序,接受來自服務(wù)端的數(shù)據(jù),一般除了本地程序以外八孝,都與服務(wù)端交互董朝,把服務(wù)端的數(shù)據(jù)或者資源渲染出來展示給用戶閱讀也可以理解為軟件,安裝在手機(jī)上的程序干跛,如果一個(gè)服務(wù)端需要接收來自其他服務(wù)端的數(shù)據(jù)子姜,那么它相對(duì)來說也是客戶端。
服務(wù)端
就是為客戶端提供服務(wù)的楼入,例如提供資源或者保存客戶端的數(shù)據(jù)哥捕,運(yùn)行服務(wù)端的終端(或者電腦)成為服務(wù)器。
NodeJS簡(jiǎn)介
什么是NodeJS
NodeJS是一個(gè)運(yùn)行在服務(wù)端的JavaScript運(yùn)行環(huán)境嘉熊,發(fā)布于2009年5月遥赚,它的實(shí)質(zhì)對(duì)chrome的js引擎(v8)的封裝,JavaScript作為一門腳本語言阐肤,而腳本語言都需要一個(gè)解析器來運(yùn)行凫佛,在客戶端,瀏覽器的js引擎就充當(dāng)了js的解析器孕惜,而在服務(wù)端愧薛,NodeJS就成為了js的解析器,解析器其實(shí)就是一個(gè)運(yùn)行環(huán)境衫画,在客戶端厚满,解析器提供了操作dom、bom的接口碧磅,而在NodeJS中,這個(gè)解析器提供了操作磁盤和搭建服務(wù)的功能遵馆。
NodeJS的產(chǎn)生
nodeJS在前端火起來是因?yàn)閚odeJS的語法與JavaScript幾乎無差別鲸郊,或者說差別很小,也就意味著前端人員學(xué)習(xí)成本小货邓,另一個(gè)是產(chǎn)生nodeJS并不是因?yàn)橛腥丝桃馊プ孞avaScript去運(yùn)行在服務(wù)端秆撮,而是因?yàn)樵髡弑旧淼墓ぷ魇抢肅/C++開發(fā)web服務(wù),對(duì)于高性能换况,異步IO职辨、事件驅(qū)動(dòng)是基本原則,但是用C/C++寫太痛苦了戈二。于是他開始設(shè)想用高級(jí)語言開發(fā)Web服務(wù)舒裤。在評(píng)估了很多種高級(jí)語言,發(fā)現(xiàn)很多語言雖然同時(shí)提供了同步IO和異步IO觉吭,但是開發(fā)人員一旦用了同步IO腾供,他們就再也懶得寫異步IO了,所以,最終他把目光看向了JavaScript伴鳖,因?yàn)镴avaScript是單線程執(zhí)行节值,根本不能進(jìn)行同步IO操作,所以榜聂,JavaScript的這一缺陷導(dǎo)致了它只能使用異步IO搞疗。
nodeJS的特點(diǎn)
非阻塞IO
在單線程中,當(dāng)一段代碼運(yùn)行需要很長時(shí)間的時(shí)候须肆,后面的代碼就會(huì)處于等待狀態(tài)匿乃,在瀏覽器端,也就是常常表現(xiàn)的瀏覽器假死休吠,比如一個(gè)沒有終止的遞歸或者一個(gè)沒有結(jié)束的for循環(huán)扳埂,而在nodejs中,采用了非阻塞的IO機(jī)制瘤礁,就是說當(dāng)一個(gè)請(qǐng)求所返回的數(shù)據(jù)需要很長時(shí)間阳懂,那么就會(huì)把這段請(qǐng)求代碼放在回調(diào)函數(shù)中,當(dāng)主線程代碼執(zhí)行完畢后再去讀取請(qǐng)求的數(shù)據(jù)柜思,不停的輪詢(Evevt Loop)岩调,直到數(shù)據(jù)正常返回,再去處理數(shù)據(jù)赡盘,從而提升了執(zhí)行效率
事件驅(qū)動(dòng)
事件驅(qū)動(dòng)編程主要思想是通過事件或狀態(tài)的變化來進(jìn)行應(yīng)用程序的流程控制号枕,一般通過事件監(jiān)聽完成,一旦事件被檢測(cè)到陨享,則調(diào)用相應(yīng)的回調(diào)函數(shù)葱淳,簡(jiǎn)單來說就是當(dāng)異步任務(wù)執(zhí)行的時(shí)候,會(huì)被放在任務(wù)隊(duì)列中抛姑,主線程執(zhí)行完畢后赞厕,會(huì)讀取任務(wù)隊(duì)列中的事件,因?yàn)槿蝿?wù)隊(duì)列中的每一個(gè)異步任務(wù)執(zhí)行完畢后都會(huì)在任務(wù)隊(duì)列中添加一個(gè)事件定硝,而js主線程執(zhí)行完后就會(huì)執(zhí)行這些事件皿桑,從而調(diào)起對(duì)應(yīng)的回調(diào)函數(shù)放入主線程中進(jìn)行執(zhí)行。
單線程
在Java或PHP中蔬啡,會(huì)為每一個(gè)客戶端鏈接創(chuàng)建一個(gè)線程诲侮,而每個(gè)線程需要大約2MB的內(nèi)存,在一個(gè)8GB的服務(wù)器上箱蟆,大約能同時(shí)為4000左右的用戶服務(wù)沟绪,而NodeJS通過非阻塞IO、事件驅(qū)動(dòng)機(jī)制空猜,可以同時(shí)處理超過4萬的用戶連接近零,缺點(diǎn)就是一個(gè)用戶造成的線程崩潰會(huì)讓整個(gè)服務(wù)器都崩潰诺核,其他用戶也會(huì)崩潰
單線程在同一時(shí)刻只能執(zhí)行一個(gè)任務(wù),也就是說久信,執(zhí)行環(huán)境相對(duì)更簡(jiǎn)單窖杀,更高效,但是在單線程中IO設(shè)備對(duì)其來說是致命的裙士,因?yàn)镮O是阻塞形式的入客,然而在NodeJS中,將異步數(shù)據(jù)放在任務(wù)隊(duì)列中執(zhí)行腿椎,從而不阻塞主線程任務(wù)的執(zhí)行桌硫,當(dāng)異步任務(wù)執(zhí)行完畢后,在任務(wù)隊(duì)列中添加事件等待執(zhí)行啃炸,從而提高了效率铆隘。
跨平臺(tái)
NodeJS是服務(wù)端的,基于chrome的V8引擎南用,是javaScript的運(yùn)行環(huán)境膀钠,因此沒有運(yùn)行的限制,與瀏覽器沒有任何關(guān)系裹虫,并不會(huì)因?yàn)镮E而長盛兼容問題等肿嘲。
與NodeJS的特點(diǎn)有關(guān)的問題,可是面試中經(jīng)常遇到的筑公,看官看完不打算收藏一下嗎雳窟?