成人免费看黄网站无遮挡,caowo999,se94se欧美综合色,a级精品九九九大片免费看,欧美首页,波多野结衣一二三级,日韩亚洲欧美综合

研究Promise 方式實(shí)現Node.js 實(shí)踐應用論文

時(shí)間:2021-04-15 09:58:47 論文 我要投稿

研究Promise 方式實(shí)現Node.js 實(shí)踐應用論文

  Node.js 是建立在Chrome V8 引擎的javaScript 運行時(shí)之上的平臺, 用于構建快速、可擴展的Web 應用程序. Node.js 采用單線(xiàn)程、事件驅動(dòng)、非阻塞的I/O模型, 這些特性不僅帶來(lái)了巨大的性能提升, 還減少了多線(xiàn)程程序設計的復雜性, 進(jìn)而提高了開(kāi)發(fā)效率,使其輕量又高效. 傳統的Node.js 在處理異步問(wèn)題時(shí),一般采用的是callback 回調的方式. callback 回調存在一個(gè)很?chē)乐氐慕鹱炙䥺?wèn)題——大量的回調函數慢慢向右側屏幕延伸的一種狀態(tài).

研究Promise 方式實(shí)現Node.js 實(shí)踐應用論文

  Promise 是異步編程的一種解決方案, 比傳統的解決方案——回調函數和事件, 更合理和強大. 它最早由javascript 社區提出和實(shí)現, 目前最新的JavaScript語(yǔ)言標準ES6 已將其寫(xiě)進(jìn)了標準中, 統一了用法, 原生提供了Promise 對象. 借助Promise 對象, 可以將異步操作以同步操作的流程表達出來(lái), 避免了層層嵌套的回調函數.

  本文就是采用Promise 方式在Node.js 平臺上搭建了一個(gè)網(wǎng)絡(luò )爬蟲(chóng)的應用. 本文首先介紹了Node.js 平臺以及其相關(guān)的一些特點(diǎn)和概念, 然后在此基礎上, 針對其傳統的callback 的回調方式的“回調地獄”等問(wèn)題,引入了Promise 對象來(lái)處理這種異步回調的問(wèn)題. 通過(guò)深入分析Promise 對象的理論知識以及規范, 將其合理地運用到網(wǎng)絡(luò )爬蟲(chóng)的應用中去. 最后通過(guò)爬取一個(gè)課程網(wǎng)站的視頻課程信息, 充分展示了Node.js 平臺的強大和方便, 以及Promise 對象在處理異步回調問(wèn)題上的優(yōu)越性以及新思路.

  1.Node.js平臺介紹

  Node.js 是一位叫Ryan Dahl 的程序員發(fā)明的. 他的工作是用C/C++寫(xiě)高性能Web 服務(wù). 對于高性能,異步IO、事件驅動(dòng)是基本原則, 但是用C/C++寫(xiě)就太痛苦了. 于是Ryan 開(kāi)始設想用高級語(yǔ)言開(kāi)發(fā)Web 服務(wù).他評估了很多種高級語(yǔ)言, 發(fā)現很多語(yǔ)言雖然同時(shí)提供了同步IO 和異步IO, 但是開(kāi)發(fā)人員一旦用了同步IO, 他們就再也懶得寫(xiě)異步IO 了, 所以, 最終, Ryan瞄向了JavaScript. 因為JavaScript 是單線(xiàn)程執行, 根本不能進(jìn)行同步IO 操作, 所以, JavaScript 的這一“缺陷”導致了它只能使用異步IO.

  選定了開(kāi)發(fā)語(yǔ)言, 還要有運行時(shí)引擎. Ryan 曾考慮過(guò)自己寫(xiě)一個(gè), 不過(guò)明智地放棄了, 因為V8 就是開(kāi)源的JavaScript 引擎. 讓Google 投資去優(yōu)化V8, 我們只管拿過(guò)來(lái)用就好了.于是在2009 年, Ryan 正式推出了基于JavaScript語(yǔ)言和V8 引擎的開(kāi)源Web 服務(wù)器項目, 命名為Node.js. Node 第一次把JavaScript 帶入到后端服務(wù)器開(kāi)發(fā), 加上世界上已經(jīng)有無(wú)數的JavaScript 開(kāi)發(fā)人員,所以Node.js 一下子就火了起來(lái).Node.js 主要特點(diǎn)是(1)時(shí)間驅動(dòng)、異步編程; (2)單進(jìn)程單線(xiàn)程.

  1.1 事件驅動(dòng)、異步編程

  事件驅動(dòng)并不是Node.js 專(zhuān)屬, 在某些傳統語(yǔ)言的網(wǎng)絡(luò )編程中, 我們會(huì )用到回調函數, 比如當socket 資源達到某種狀態(tài)時(shí), 注冊的回調函數就會(huì )執行.Node.js 的設計思想中以事件驅動(dòng)為核心, 它提供的絕大多數API 都是基于事件的、異步的風(fēng)格. 以Net 模塊為例, 其中的net.Socket 對象就有以下事件:connect、data、end、timeout、drain、error、close 等, 使用Node.js 的開(kāi)發(fā)人員需要根據自己的業(yè)務(wù)邏輯注冊相應的回調函數. 這些回調函數都是異步執行的, 這意味著(zhù)雖然在代碼結構中, 這些函數看似是依次注冊的, 但是它們并不依賴(lài)于自身出現的順序, 而是等待相應的事件觸發(fā). 事件驅動(dòng)、異步編程的設計重要的優(yōu)勢在于, 充分利用了系統資源, 執行代碼無(wú)須阻塞等待某種操作完成, 有限的資源可以用于其他的任務(wù).此類(lèi)設計非常適合于后端的網(wǎng)絡(luò )服務(wù)編程, Node.js 的目標也在于此. 在服務(wù)器開(kāi)發(fā)中, 并發(fā)的請求處理是個(gè)大問(wèn)題, 阻塞式的函數會(huì )導致資源浪費和時(shí)間延遲.通過(guò)事件注冊、異步函數, 開(kāi)發(fā)人員可以提高資源的利用率, 性能也會(huì )改善.從Node.js 提供的支持模塊中, 我們可以看到包括文件操作在內的許多函數都是異步執行的, 這和傳統語(yǔ)言存在區別, 而且為了方便服務(wù)器開(kāi)發(fā), Node.js 的網(wǎng)絡(luò )模塊特別多, 包括HTTP、DNS、NET、UDP、HTTPS、TLS 等, 開(kāi)發(fā)人員可以在此基礎上快速構建Web 服務(wù)器.

  1.2 單進(jìn)程單線(xiàn)程

  1.2.1 高性能

  Node.js 單線(xiàn)程模式避免了傳統php 那樣頻繁創(chuàng )建、切換線(xiàn)程的花銷(xiāo), 執行速度更快. 而且, 資源占用小, Node.js 在大負荷下對內存占用任然很低.

  1.2.2 線(xiàn)程安全

  單線(xiàn)程的node.js 還保證了絕對的線(xiàn)程安全, 不用擔心統一變量同時(shí)被多個(gè)線(xiàn)程進(jìn)行讀寫(xiě)而造成程序崩潰. 線(xiàn)程安全的同時(shí)也解放了開(kāi)發(fā)人員, 免去了多線(xiàn)程編程中忘記對變量加鎖或者解鎖造成的隱患.

  2.Promise

  Promise 主要解決JavaScript 中異步的場(chǎng)景.Promise 是個(gè)對象, 同JavaScript 中其它對象沒(méi)什么區別, 但同時(shí)它也是一個(gè)規范, 針對異步操作約定了統一的接口, 表示一個(gè)一步操作最終的結果, 以同步的方式來(lái)寫(xiě)代碼, 執行的操作是異步的, 但是又保證程序的執行順序是同步的. 這原本是JavaScript 社區的一個(gè)規范的構想, 現在已經(jīng)被加入到了ES6 的語(yǔ)言標準中, Firefox 和Chrome 等瀏覽器已經(jīng)對它進(jìn)行了實(shí)現.

  2.1 同步與異步

  JS 引擎是單線(xiàn)程的. 這意味著(zhù)在任何環(huán)境中, 只有一段JS 代碼會(huì )被執行. 每個(gè)函數是一個(gè)不可分割的片段或者代碼塊. 當JS 引擎開(kāi)始執行一個(gè)函數(比如回調函數)時(shí), 它就會(huì )把這個(gè)函數執行完, 只有執行完這段代碼才會(huì )繼續執行后面的代碼. 這就是JS 中的同步. Promise 對象的then()方法就是同步處理每個(gè)Promise 對象.異步是指在執行一段代碼時(shí), 這段代碼依賴(lài)一些其他的操作或者數據, 這時(shí)就不用等待數據或者操作的返回, 直接執行下一段代碼, 當有數據或操作返回時(shí)再去響應之前的代碼, 從而提高代碼執行的效率.

  2.2 Promise 對象的狀態(tài)

  Promise 對象只有三種狀態(tài):

  (1) Pending: 初始狀態(tài), 進(jìn)行中.

  (2) Resolved(或Fulfilled): 成功的操作.

  (3) Rejected: 失敗的操作.

  (1) Promise 對象的狀態(tài)不受外界影響.

  Promise 對象代表一個(gè)異步操作, 有三種狀態(tài):Pending(進(jìn)行中)、Resolved(已完成, 又稱(chēng)Fulfilled)和Rejected(已失敗). 只有異步操作的結果, 可以決定當前是哪一種狀態(tài), 任何其他操作都無(wú)法改變這個(gè)狀態(tài).

  (2) Promise 對象一旦狀態(tài)改變, 就不會(huì )再變, 任何時(shí)候都可以得到這個(gè)結果.Promise 對象的狀態(tài)改變, 只有兩種可能: 從Pending 變?yōu)镽esolved 和從Pending 變?yōu)镽ejected. 只要這兩種情況發(fā)生, 狀態(tài)就凝固了, 不會(huì )再變了, 會(huì )一直保持這個(gè)結果. 就算改變已經(jīng)發(fā)生了, 再對Promise 對象添加回調函數, 也會(huì )立即得到這個(gè)結果.

  2.3 Promise 的核心方法

  Promise 對象的核心部件是它的then 方法, 它的作用是為Promise 實(shí)例添加狀態(tài)改變時(shí)的回調函數. then方法接受兩個(gè)回調函數作為參數. 第一個(gè)回調函數是Promise 對象的狀態(tài)變?yōu)镽esolved 時(shí)調用, 第二個(gè)回調函數是Promise 對象的狀態(tài)變?yōu)镽ejected 時(shí)調用. 其中,第二個(gè)函數是可選的, 不一定要提供. 這兩個(gè)函數都接受Promise 對象傳出的值作為參數.Promise 對象另一個(gè)核心方法是它的catch 方法,用于指定發(fā)生錯誤時(shí)的回調函數, 是then(null,rejection)的別名. catch 方法可以捕捉promise 實(shí)例中的異常還能捕獲在它之前太狠方法中發(fā)生的異常, 所以在實(shí)際的使用中, 多用catch 方法來(lái)取代then(null,rejection)處理異常.

  3.爬蟲(chóng)應用設計與實(shí)現

  3.1 模塊加載

  新建一個(gè)promise_crawler.js 文件, 首先把需要的相應的模塊加載進(jìn)來(lái).http 模塊: 主要用于搭建 HTTP 服務(wù)端和客戶(hù)端,使用 HTTP 服務(wù)器或客戶(hù)端功能必須調用 http 模塊;bluebird 模塊: Promise 類(lèi)庫(在最新的Node.js 里已經(jīng)引入了Promise 模塊, 可直接使用, 但考慮到兼容性問(wèn)題, 本例中采用bluebird 模塊);cheerio 模塊: 類(lèi)似于前端的jQuery, 能夠簡(jiǎn)單方便地操作裝在后臺的html.

  3.2 組織數據結構

  首先在chrome 瀏覽器中打開(kāi)需要爬取的網(wǎng)頁(yè), 同時(shí)打開(kāi)控制臺查看網(wǎng)頁(yè)html DOM 結構, 分析出所需信息, 組織好數據結構, 然后根據DOM結構去獲取所需信息.

  3.3 Promise 主要流程

  本例中完成的主要功能是, 同時(shí)爬取一個(gè)課程網(wǎng)站的多個(gè)頁(yè)面, 獲取相關(guān)信息, 然后將數據按照組織好的數據結構打印出來(lái).代碼中所用到的Promise.all 方法用于將多個(gè)Promise 實(shí)例, 包裝成一個(gè)新的Promise 實(shí)例.該方法接收一個(gè)Promise 對象數組作為參數, p1、p2、p3 都是Promise 對象的實(shí)例.p 的狀態(tài)由p1、p2、p3 決定, 分成兩種情況.

  (1) 只有p1、p2、p3 的狀態(tài)都變成Resolved, p 的狀態(tài)才會(huì )變成Resolved, 此時(shí)p1、p2、p3 的返回值組成一個(gè)數組, 傳遞給p 的回調函數.

  (2) 只要p1、p2、p3 之中有一個(gè)被rejected, p 的狀態(tài)就變成Rejected, 此時(shí)第一個(gè)被Rejected 的實(shí)例的返回值, 會(huì )傳遞給p 的回調函數.

  3.4 相關(guān)函數實(shí)現

  3.4.1 爬取頁(yè)面getPageAsync(url)

  通過(guò)http 模塊的get 方法爬取頁(yè)面數據, 最后返回一個(gè)Promise 對象, 方便異步處理.

  3.4.2 過(guò)濾數據filterChapters(html)

  過(guò)濾出每個(gè)頁(yè)面所需的`數據, 然后按一定的數據結構組織起來(lái).

  3.4.3 打印數據printCourseInfo(coursesData)

  將爬取到的數據, 按照組織好的數據結構打印出來(lái).

  3.4 實(shí)驗結果

  執行promise_crawler.js 文件, 即可看到輸出的相關(guān)信息實(shí)驗中同爬取了4 個(gè)頁(yè)面, 可以看到, 實(shí)驗結果是按照代碼中設定好的數據結構爬取并打印出來(lái)的,符合實(shí)驗預期. Promise 對象是基于異步的方式來(lái)處理程序的. 爬取每個(gè)頁(yè)面時(shí), 不用等待頁(yè)面的數據處理完畢再去爬取下一個(gè)頁(yè)面, 而是無(wú)阻塞不間斷的去爬取每個(gè)頁(yè)面, 當有異步的數據返回時(shí)調用Promise 對象的resolve()方法去處理, 出現錯誤異常時(shí)調用reject()方法去解決. 當有多個(gè)Promise 對象時(shí), 調用then(onFulfilled)方法, 同步處理每個(gè)Promise 對象, 一旦處理哪個(gè)Promise 對象出錯時(shí), 可以立即調用catch方法處理異常, 中止程序往下執行, 及時(shí)發(fā)現錯誤.而且onFulfilled()方法每次返回的是新的Promise 對象,這樣保證了then()可以一直鏈式調用下去, 提高了程序的效率和可靠性.

  4.結語(yǔ)

  Node.js 作為一門(mén)新興的技術(shù), 打通了前后端的界限. 由于采用事件驅動(dòng)和無(wú)阻塞模型, 可以很方便的構建高效、可擴展的網(wǎng)絡(luò )應用, 這是Node.js 最大的一個(gè)優(yōu)點(diǎn), 同時(shí)也是最大的一個(gè)缺點(diǎn), 由于事件驅動(dòng)和無(wú)阻塞模型是建立在callback 這種回調方式上的, 隨著(zhù)回調的增加, 代碼嵌套的層次就會(huì )增加, 這樣很容易陷入“回調地獄”, 這種代碼難以編寫(xiě), 難以理解而且難以維護.Promise 對象是解決Node.js 中異步回調的一種很有效的方式. 借助Promise 對象, 可以將異步操作以同步操作的流程表達出來(lái), 避免了層層嵌套的回調函數.在保證異步回調的基礎上又實(shí)現了多個(gè)promise 對象之間的同步順序, 使程序能快速高效的執行下去, 給我們的開(kāi)發(fā)帶來(lái)很大的便利.

【研究Promise 方式實(shí)現Node.js 實(shí)踐應用論文】相關(guān)文章:

培養高職學(xué)生主動(dòng)意識的實(shí)踐與探索的方式研究論文12-11

自我傳播的途徑與方式研究論文11-03

轉變農業(yè)發(fā)展方式研究論文05-23

中職學(xué)生行為方式研究論文06-18

關(guān)于PLC實(shí)現高爐料流閥自修正控制的研究與應用的論文07-18

預防醫學(xué)實(shí)踐教學(xué)改革的應用研究論文07-31

Proteus在電子實(shí)踐教學(xué)課程中應用的研究論文01-23

網(wǎng)站設計的實(shí)現技術(shù)研究論文10-24

無(wú)線(xiàn)通信SCADA系統的實(shí)現與應用論文07-08