最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

node.js監(jiān)聽文件變化的實現(xiàn)方法

 更新時間:2019年04月17日 11:27:59   作者:瀟湘待雨  
這篇文章主要給大家介紹了關于node.js監(jiān)聽文件變化的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家學習或者使用node.js具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧

前言

隨著前端技術的飛速發(fā)展,前端開發(fā)也從原始的刀耕火種,向著工程化效率化的方向發(fā)展。在各種開發(fā)框架之外,打包編譯等技術也是層出不窮,開發(fā)體驗也是越來越好。例如HMR,讓我們的更新可以即時可見,告別了手動F5的情況。其實現(xiàn)就是監(jiān)聽文件變化自動調用構建過程。下面就關注下如何實現(xiàn)node監(jiān)聽文件變化。

場景

假定要監(jiān)聽index.js,每當內容更改重新編譯。

我們就用簡單的console來標識執(zhí)行編譯。下面就是實現(xiàn)該功能。

node原生API

fs.watchFile

翻下node的文檔就會看到一個滿足我們需求的Apifs.watchFile(畢竟是文件相關的操作,很大可能就在fs模塊下面了)。

fs.watchFile(filename[, options], listener)
  • filename 顯然就是文件名
  • options 可選 對象 包含以下兩個屬性
    • persistent 文件被監(jiān)聽時進程是否繼續(xù),默認true
    • interval 多長時間輪訓一次目標文件,默認5007毫秒
  • listener 事件回調 包含兩個參數(shù)
    • current 當前文件stat對象
    • prev 之前文件stat對象

看完參數(shù)信息,不知道大家有沒有從其參數(shù)屬性中得到點什么特別的信息。特別是interval選項和listener中的回調參數(shù)。

監(jiān)控filename對應文件,每當訪問文件時會觸發(fā)回調。

這里每當訪問文件時會觸發(fā),實際指的是每次切換之后再次進入文件,然后保存之后,無論是否做了修改都會出發(fā)回調。

另外輪詢事件和文件對象,是不是可以猜測,其實現(xiàn)監(jiān)聽的原理,固定時間輪詢文件狀態(tài),然后將前后的狀態(tài)返回,將判斷交給使用者。

所以node也建議,如果要獲取文件修改,那么需要根據stat對象的修改時間來進行對比,即比較 curr.mtime 和 prev.mtime。

這樣就有點問題,我們先看下例子,會更清晰一點。

const fs = require('fs')
const filePath = './index.js'
console.log(`正在監(jiān)聽 ${filePath}`);
fs.watchFile(filePath, (cur, prv) => {
 if (filePath) {
  // 打印出修改時間
  console.log(`cur.mtime>>${cur.mtime.toLocaleString()}`)
  console.log(`prv.mtime>>${prv.mtime.toLocaleString()}`)
  // 根據修改時間判斷做下區(qū)分,以分辨是否更改
  if (cur.mtime != prv.mtime){
   console.log(`${filePath}文件發(fā)生更新`)
  }
 }
})

然后測試結果如下:

// 運行
node watch1.js
// 1、訪問index.js 不做修改,然后保存
// 2、切換文件,再次訪問,不做修改,只報錯
// 3、編輯內容,并保存


可以看到1、2兩步,并沒有實際修改內容,然而我們并沒有辦法區(qū)分。只要你是切換之后再保存,修改時間戳mtime就發(fā)生變化。

另外響應時間真的很慢,畢竟是輪詢。

對于這些問題,其實官網也給了一句話:

Using fs.watch() is more efficient than fs.watchFile and fs.unwatchFile. fs.watch should be used instead of fs.watchFile and fs.unwatchFile when possible.

能用fs.watch的情況就不要用watchFile了。一是效率,二是不能準確獲知修改狀態(tài) 三是只能監(jiān)聽單獨文件
對于實際開發(fā)過程中,顯然我們想要關注的是源文件夾的變動。

fs.watch

首先用法如下:

fs.watch(filename[, options][, listener])

跟fs.watchFile比較類似。

  • filename 顯然就是文件名
  • options 可選 對象或者字符串 包含以下三個屬性
    • persistent 文件被監(jiān)聽時進程是否繼續(xù),默認true
    • recursive 是否監(jiān)控所有子目錄,默認false 即當前目錄,true為所有子目錄。
    • encoding 指定傳遞給回調事件的文件名稱,默認utf8
  • listener 事件回調 包含兩個參數(shù)
    • eventType 事件類型,rename 或者 change
    • filename 當前變更文件的文件名

options如果是字符串,指的是encoding。

監(jiān)聽filename對應的文件或者文件夾(recursive參數(shù)也體現(xiàn)出來這一特性),返回一個fs.FSWatcher對象。

該功能的實現(xiàn)依賴于底層操作系統(tǒng)的對于文件更改的通知。 所以就存在一個問題,可能不同平臺的實現(xiàn)不太相同。
如下示例1:

const fs = require('fs')
const filePath = './' 
console.log(`正在監(jiān)聽 ${filePath}`);
fs.watch(filePath,(event,filename)=>{
 if (filename){
  console.log(`${filename}文件發(fā)生更新`)
 }
})

一個比較明顯的優(yōu)勢就體現(xiàn)出來了:響應比較及時,相比于輪詢,效率肯定更高。

不過這樣修改并保存的時候回發(fā)現(xiàn)同樣有點問題。

直接保存,顯示兩次更新

修改文件之后,同樣顯示兩次更新(mac系統(tǒng)上是兩次,其他系統(tǒng)可能有所差別)

這樣可能是于操作系統(tǒng)對文件修改的事件支持有關,在保存的時候出發(fā)了不止一次。

下面聚焦于回調事件的參數(shù),event對應事件類型,是否可以判斷事件類型為change呢,才執(zhí)行呢,忽略空保存。

const fs = require('fs')
const filePath = './'  
console.log(`正在監(jiān)聽 ${filePath}`);
fs.watch(filePath,(event,filename)=>{
  console.log(`event類型${event}`)
  if (filename && event == 'change') {
    console.log(`${filename}文件發(fā)生更新`)
  }
})

不過實際上,空的保存event也是change,另外不同平臺event的實現(xiàn)可能也有所不同。這種方式要pass掉。

校驗變更時間

顯然從上面的例子可以看到,變更時間依然不可控。因為每次保存,node對應stat對象依然會修改。

對比文件內容

只能選擇這種方式來判斷是否是否更新。例如md5:

const fs = require('fs'),
  md5 = require('md5');
const filePath = './'  
let preveMd5 = null

console.log(`正在監(jiān)聽 ${filePath}`);
fs.watch(filePath,(event,filename)=>{
  var currentMd5 = md5(fs.readFileSync(filePath + filename))
  if (currentMd5 == preveMd5) {
    return
  }
  preveMd5 = currentMd5
  console.log(`${filePath}文件發(fā)生更新`)
})

先保存當前文件md5值,每次文件變化時(即保存操作響應之后),每次都獲取文件的md5然后進行對比,看是否發(fā)生變化。

不過這樣可以看到,當初次保存時,都會執(zhí)行一次,因為初始值為null的緣故。這樣可以加個兼容,根據是否第一次保存來判斷好了。

優(yōu)化

對于不同的操作系統(tǒng),可能保存時觸發(fā)的回調不止一個(mac上到沒出現(xiàn))。為了避免這種實時響應對應的頻繁觸發(fā),可以引入debounce函數(shù)來保證性能。

const fs = require('fs'),
  md5 = require('md5');
let preveMd5 = null,
  fsWait = false
const filePath = './'  
console.log(`正在監(jiān)聽 ${filePath}`);
fs.watch(filePath,(event,filename)=>{
  if (filename){
    if (fsWait) return;
    fsWait = setTimeout(() => {
      fsWait = false;
    }, 100)
    var currentMd5 = md5(fs.readFileSync(filePath + filename))
    if (currentMd5 == preveMd5){
      return 
    }
    preveMd5 = currentMd5
    console.log(`${filePath}文件發(fā)生更新`)
  }
})

結束語

到這里,node監(jiān)聽文件的實現(xiàn)就結束了。做個學習筆記,來做個參考記錄。實現(xiàn)起來并不難,但是要實際應用的話需要考慮的方面就比較多了。還是推薦開源框架node-watch、chokidar等,各方面實現(xiàn)的都比較完善。

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。

參考文章

相關文章

  • 淺析node.js中close事件

    淺析node.js中close事件

    本文簡單介紹了http.ServerRespose對象的close事件,并給出了相關實例,推薦給需要的小伙伴參考下吧。
    2014-11-11
  • Nodejs 獲取時間加手機標識的32位標識實現(xiàn)代碼

    Nodejs 獲取時間加手機標識的32位標識實現(xiàn)代碼

    本文給大家分享nodejs獲取時間加手機標識的32位標識實現(xiàn)代碼,非常不錯,具有參考借鑒價值,需要的朋友參考下
    2017-03-03
  • 阿里云ecs服務器中安裝部署node.js的步驟

    阿里云ecs服務器中安裝部署node.js的步驟

    這篇文章給大家介紹了在阿里云ecs服務器中安裝部署node.js的詳細步驟,對大家安裝node.js具有一定的參考借鑒價值,有需要的朋友們下面來一起看看吧。
    2016-10-10
  • 在nodejs中使用swagger方式

    在nodejs中使用swagger方式

    這篇文章主要介紹了在nodejs中使用swagger方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 在Node.js中使用HTTP上傳文件的方法

    在Node.js中使用HTTP上傳文件的方法

    這篇文章主要介紹了在Node.js中使用HTTP上傳文件的方法,作者以windows下的visual studio作為操作node的環(huán)境,推薦閱讀!需要的朋友可以參考下
    2015-06-06
  • node.js環(huán)境搭建圖文詳解

    node.js環(huán)境搭建圖文詳解

    Node.js 是一個讓 JavaScript 運行在服務端的開發(fā)平臺,小編在空閑時間就研究nodejs的相關知識,下面是本文給大家?guī)淼膎ode.js環(huán)境搭建教程圖解,感興趣的朋友跟隨小編一起學習吧
    2018-09-09
  • node基于puppeteer模擬登錄抓取頁面的實現(xiàn)

    node基于puppeteer模擬登錄抓取頁面的實現(xiàn)

    本篇文章主要介紹了node基于puppeteer模擬登錄抓取頁面的實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • Nodejs全??蚣躍trongLoop推薦

    Nodejs全??蚣躍trongLoop推薦

    StrongLoop基本提供了制作一個移動產品所有的框架和工具,從標準的Backend server,Devops,應用監(jiān)控,。要想介紹完全StrongLoop的所有產品得寫一個長篇連載了,這里只簡單的瀏覽一遍。
    2014-11-11
  • NodeJS通過魔術封包喚醒局域網計算機實例

    NodeJS通過魔術封包喚醒局域網計算機實例

    這篇文章主要為大家介紹了NodeJS通過魔術封包喚醒局域網計算機代碼實例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • Thinkjs3新手入門之如何使用靜態(tài)資源目錄

    Thinkjs3新手入門之如何使用靜態(tài)資源目錄

    最近在學習thinkjs3,發(fā)現(xiàn)有些地方還是有必要整理下的,下面這篇文章主要給大家介紹了關于Thinkjs3新手入門之如何使用靜態(tài)資源目錄的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下。
    2017-12-12

最新評論

彭泽县| 湖州市| 清新县| 林芝县| 杭锦旗| 托里县| 三门峡市| 上栗县| 芦山县| 南皮县| 图木舒克市| 安仁县| 通化市| 郯城县| 沅陵县| 黔南| 抚远县| 武汉市| 上杭县| 遂溪县| 易门县| 青海省| 札达县| 南木林县| 东光县| 沧州市| 陆丰市| 张北县| 凌云县| 德安县| 石泉县| 申扎县| 崇阳县| 砀山县| 游戏| 岗巴县| 凉城县| 衡东县| 长海县| 遵义县| 新干县|