Node.js中怎么實(shí)現(xiàn)異步編程

Node.js中怎么實(shí)現(xiàn)異步編程,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

創(chuàng)新互聯(lián)建站專業(yè)為企業(yè)提供金城江網(wǎng)站建設(shè)、金城江做網(wǎng)站、金城江網(wǎng)站設(shè)計(jì)、金城江網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、金城江企業(yè)網(wǎng)站模板建站服務(wù),10余年金城江做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

 其實(shí)對(duì)大部分的開發(fā)者來(lái)說,異步編程與一般自然語(yǔ)言的線性思維會(huì)有所沖突。所以大部分開發(fā)者不能適應(yīng)直接面向事件驅(qū)動(dòng)進(jìn)行編程,Node.js是首個(gè)將異步編程帶到應(yīng)用層面的平臺(tái),Node.js無(wú)時(shí)無(wú)刻不透露出異步的信息。

在接觸Node的過程中,很多人只是很粗略的接觸了幾個(gè)回調(diào)函數(shù)之后就放棄了,確實(shí)Node使用異步編程,容易陷入回調(diào)地獄,但是Node異步編程的難題其實(shí)已經(jīng)基本解決,可以通過事件發(fā)布/訂閱模式,或者通過Promise/Defferred模式,其實(shí)都可以完美的去解決回調(diào)陷阱的問題。

其實(shí)大部分開發(fā)人員都習(xí)慣線性思維去思考問題,所以同步編程一直很流行。但是單線程同步模型中,CPUI/O操作無(wú)法重疊進(jìn)行,所以性能問題也就擺在了開發(fā)人員的面前。在大多數(shù)語(yǔ)言中,提高性能的方式一般使用多線程的方式解決,但是多線程中線程切換耗費(fèi)的開銷,以及鎖以及線程同步等問題,所以多線程會(huì)給開發(fā)人員業(yè)務(wù)邏輯帶來(lái)麻煩。而Node直接采用異步編程,可以使CPUI/O操作并行不用相互等待,可以讓資源等到更好的利用。

異步IO與非阻塞IO的區(qū)別

非阻塞IO是由于完整的I/O沒有完成,立即返回的并不是我們執(zhí)行的最終數(shù)據(jù),而僅僅是返回當(dāng)前的調(diào)用狀態(tài),為了獲得完整數(shù)據(jù)需要進(jìn)行輪詢重復(fù)調(diào)用I/O操作確認(rèn)是否完成。異步I/O可實(shí)現(xiàn)不等待數(shù)據(jù)讀取完成,執(zhí)行I/O操作后后立刻返回,數(shù)據(jù)寫入緩存,由底層完成監(jiān)聽操作,并返回成功或失敗的信息給應(yīng)用。

異步編程優(yōu)點(diǎn)

Node.js最大的優(yōu)點(diǎn)莫過于基于事件驅(qū)動(dòng)的非阻塞I/O模型,非阻塞I/O可以使CPUI/O操作不用相互等待,可以讓資源可以得到更好的利用。Node.js為了解決編程模型中阻塞I/O的性能問題,采用單線程異步模型,所以Node.js更適合I/O密集型問題,因?yàn)?strong>Node.js面向驅(qū)動(dòng)進(jìn)行編程,所以需要面對(duì)海量請(qǐng)求,當(dāng)海量請(qǐng)求同時(shí)作用在單線程上時(shí),就需要防止任何一個(gè)會(huì)過度消耗時(shí)間片的請(qǐng)求。所以只要合理利用Node.js的異步模型,加上V8引擎的高性能,就可以充分發(fā)揮CPUI/O并行的優(yōu)勢(shì)。

異步編程的難點(diǎn)

Node.js借助異步I/O模型以及V8引擎,突破了單線程的性能瓶頸,讓JavaScript在后端體現(xiàn)了實(shí)用價(jià)值。但是也由于異步編程會(huì)給開發(fā)者帶來(lái)一些難點(diǎn)。

(1)函數(shù)嵌套過深

在前端JavScript,DOM事件綁定一般較少存在多重事件綁定的情況。一般為不同的DOM元素綁定不同的事件。

Node.js中怎么實(shí)現(xiàn)異步編程

但是對(duì)于Node.js而言,多個(gè)異步調(diào)用的場(chǎng)景比比皆是。

Node.js中怎么實(shí)現(xiàn)異步編程

其實(shí)對(duì)于最后的結(jié)果來(lái)說這樣的函數(shù)嵌套結(jié)構(gòu)是沒有任何問題的,但是這樣并沒有利用好Node.js異步I/O帶來(lái)的并行優(yōu)勢(shì)。而且函數(shù)嵌套過深,對(duì)于開發(fā)人員的后期維護(hù)也會(huì)造成困難。

(2)阻塞代碼

JavaScript,并沒有類似Javasleep()這樣的線程沉睡功能,可以進(jìn)行延時(shí)操作的只有setInterval()setTimeout()這兩個(gè)函數(shù)。那么如果我們需要在JavaScript中實(shí)現(xiàn)延遲1s要怎么做呢?其實(shí)大部分開發(fā)者可能會(huì)這么去進(jìn)行實(shí)現(xiàn):

Node.js中怎么實(shí)現(xiàn)異步編程

但是請(qǐng)記住Node.js是單線程模型,所以在執(zhí)行的時(shí)候CPU資源會(huì)全部為了這段代碼進(jìn)行服務(wù)。從而導(dǎo)致其他請(qǐng)求全部被視而不見。所以我們可以采用setTimeout改寫一下代碼效果會(huì)更好:

Node.js中怎么實(shí)現(xiàn)異步編程

但是這里有一個(gè)問題,如果我把后面的時(shí)間設(shè)成0,是不是意味著馬上執(zhí)行代碼呢?這個(gè)問題大家可以思考一下,對(duì)答案感興趣的可以直接在公眾號(hào)發(fā)消息,我會(huì)及時(shí)回復(fù)。

(3)多線程編程

因?yàn)?strong>Node.js是單線程模型,對(duì)于多核CPU服務(wù)端而言,其實(shí)Node.js單進(jìn)程是沒有充分利用好多核CPU的,所以瀏覽器可以將JavaScriptUI渲染分離,就可以更好的去利用多核CPU為大量計(jì)算做服務(wù)。但是這種開發(fā)模式開發(fā)者要面臨跨線程的編程,對(duì)于JavaScript一直走的單線程編程路線來(lái)說會(huì)增加一定的難度。

(4)異常處理

我們?cè)谑褂?strong>Java進(jìn)行異常處理其實(shí)是非常方便的,可以直接通過try/catch/finally語(yǔ)句進(jìn)行異常捕獲以及異常處理。

Node.js中怎么實(shí)現(xiàn)異步編程

但是在異步編程中這種常用的異常處理并不一定適用,因?yàn)榍懊嬗兄v過異步編程時(shí)異步I/O提交請(qǐng)求后馬上返回,因?yàn)楫惓R话悴粫?huì)發(fā)生在此階段,這時(shí)候你對(duì)這段代碼執(zhí)行try/catch操作進(jìn)行異常捕獲其實(shí)不會(huì)發(fā)揮作用,因?yàn)?strong>try/catch只能捕獲當(dāng)次事件內(nèi)發(fā)生的異常,對(duì)事件執(zhí)行結(jié)束返回的回調(diào)函數(shù)callback中拋出的異常其實(shí)是無(wú)能為力的,所以在Node.js中,將異常作為回調(diào)函數(shù)callback的第一個(gè)參數(shù)傳回,如果為空時(shí),則表示回調(diào)函數(shù)沒有拋出任何異常。

Node.js中怎么實(shí)現(xiàn)異步編程

上述代碼中,執(zhí)行checkLogin如果出現(xiàn)異常,則回調(diào)函數(shù)的第一個(gè)參數(shù)err則不為空,我們就可以根據(jù)這個(gè)err參數(shù)對(duì)異常進(jìn)行處理。

異步編程解決方案

(1)事件發(fā)布/訂閱模式

(2)Promise/Deferred模式

(3)流程控制庫(kù)

由于這三種方案涉及知識(shí)點(diǎn)較雜,這篇文章暫時(shí)不對(duì)這三種方案作具體介紹,下一篇文章會(huì)對(duì)這三種方案作具體介紹。

異步并發(fā)控制

Node.js中,我們可以很輕易的利用異步發(fā)起并行調(diào)用,但是如果并發(fā)量過大,我們的服務(wù)器會(huì)承受不住,比如如果是對(duì)文件系統(tǒng)進(jìn)行大量并發(fā)調(diào)用,操作系統(tǒng)的文件描述符數(shù)量會(huì)在瞬間被用光。所以對(duì)于異步編程來(lái)說并發(fā)很容易實(shí)現(xiàn),但是也要有一定的過載保護(hù)。這里主要講一種過載解決方案:async.

async提供了一個(gè)方法parallelLimit()用于處理異步調(diào)用的限制。

Node.js中怎么實(shí)現(xiàn)異步編程

parallelLimit()方法有一個(gè)用于限制并發(fā)數(shù)量的參數(shù),使得任務(wù)只能同時(shí)并發(fā)一定數(shù)量,而不能無(wú)限量同時(shí)并發(fā)。上面的代碼,我們并發(fā)數(shù)設(shè)置為1,所以只能同時(shí)并發(fā)一個(gè)任務(wù)。

但是parallelLimit()有一個(gè)缺點(diǎn):無(wú)法動(dòng)態(tài)的添加并行任務(wù)。但是async提供了queue()方法可以動(dòng)態(tài)添加并行任務(wù),這對(duì)于遍歷文件目錄等操作是非常高效的。但是queue()接收的參數(shù)是固定的,丟失了parallelLimit()的多樣性。

Node.js中怎么實(shí)現(xiàn)異步編程

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。

新聞標(biāo)題:Node.js中怎么實(shí)現(xiàn)異步編程
轉(zhuǎn)載來(lái)于:http://bm7419.com/article24/gegice.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站改版、移動(dòng)網(wǎng)站建設(shè)、網(wǎng)站排名品牌網(wǎng)站制作、網(wǎng)站設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司