精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

NodeJS中的模塊是單例的嗎?

開發(fā) 前端
筆者之前在使用require導(dǎo)入模塊時(shí),特別是在導(dǎo)入有狀態(tài)的模塊時(shí),筆者會(huì)考慮其是否在多次導(dǎo)入情況下依然保持單例特性,或者說對(duì)于同一個(gè)文件在不同路徑下導(dǎo)入時(shí),是否能夠識(shí)別為一致?本文即是對(duì)該特性進(jìn)行解析。

本文翻譯自 Lazlojuly 的 are-node-js-modules-singletons。

本文從屬于筆者的NodeJS入門與***實(shí)踐中的NodeJS 基礎(chǔ)系列文章,包括NodeJS 入門、NodeJS 模塊導(dǎo)出與解析、NodeJS IOStream、NodeJS HTTPS這幾部分。

筆者之前在使用require導(dǎo)入模塊時(shí),特別是在導(dǎo)入有狀態(tài)的模塊時(shí),筆者會(huì)考慮其是否在多次導(dǎo)入情況下依然保持單例特性,或者說對(duì)于同一個(gè)文件在不同路徑下導(dǎo)入時(shí),是否能夠識(shí)別為一致?本文即是對(duì)該特性進(jìn)行解析。

 NodeJS的模塊默認(rèn)情況下是單例性質(zhì)的,不過其并不能保證如我們編程時(shí)設(shè)想的那樣一定是單例,根據(jù)NodeJS的官方文檔中描述,某個(gè)模塊導(dǎo)入是否為單例受以下兩個(gè)因素的影響:

  • Node 模塊的緩存機(jī)制是大小寫敏感的,譬如如果你require('/foo')與require('/FOO')會(huì)返回兩個(gè)不同的對(duì)象,盡管你的foo與FOO是完全相同的文件。
  • 模塊是基于其被解析得到的文件名進(jìn)行緩存的,鑒于不同的模塊會(huì)依賴于其被調(diào)用的路徑進(jìn)行緩存鑒別,因此并不能保證你使用require('foo')會(huì)永遠(yuǎn)返回相同的對(duì)象,可能會(huì)根據(jù)不同的文件路徑得到不同的對(duì)象。

創(chuàng)建新的NodeJS模塊

根據(jù)NodeJS文檔所述,文件和模塊是一一對(duì)應(yīng)的關(guān)系。這個(gè)也是解釋上文提及的模塊緩存機(jī)制的基礎(chǔ),我們首先創(chuàng)建一個(gè)簡單的模塊:

  1. // counter.js  
  2.  
  3. let value = 0 
  4.  
  5. module.exports = { 
  6.   increment: () => value++, 
  7.   get: () => value, 

 在counter.js中我們創(chuàng)建了某個(gè)私有變量,并且只能通過公共的increment與get方法進(jìn)行操作。在應(yīng)用中我們可以如下方法使用該模塊: 

  1. // app.js 
  2. const counter = require(‘./counter.js’) 
  3.  
  4. counter.increment() 
  5. counter.increment() 
  6.  
  7. console.log(counter.get()) // prints 2 
  8. console.log(counter.value) // prints undefined as value is private  

Module Caching

NodeJS會(huì)在***次導(dǎo)入某個(gè)模塊之后將該模塊進(jìn)行緩存,在官方文檔中有如下描述:

Every call to require(‘foo’) will get exactly the same object returned, if it would resolve to the same file.

我們也可以通過如下簡單的例子來驗(yàn)證這句話: 

  1. // app-singleton.js 
  2.  
  3. const counter1 = require(‘./counter.js’) 
  4. const counter2 = require(‘./counter.js’) 
  5.  
  6. counter1.increment() 
  7. counter1.increment() 
  8. counter2.increment() 
  9.  
  10. console.log(counter1.get()) // prints 3 
  11. console.log(counter2.get()) // also prints 3  

可以看出盡管我們兩次導(dǎo)入了該模塊,但是還是指向了同一個(gè)對(duì)象。不過并不是每次我們導(dǎo)入同一個(gè)模塊時(shí),都會(huì)得到相同的對(duì)象。在NodeJS中,模塊對(duì)象有個(gè)內(nèi)置的方法:Module._resolveFilename(),其負(fù)責(zé)尋找require中合適的模塊,在找到正確的文件之后,會(huì)根據(jù)其文件名作為緩存的鍵名。官方的搜索算法偽代碼為: 

  1. require(X) from module at path Y 
  2. 1. If X is a core module, 
  3.    a. return the core module 
  4.    b. STOP 
  5. 2. If X begins with './' or '/' or '../' 
  6. a. LOAD_AS_FILE(Y + X) 
  7.       1. If X is a file, load X as JavaScript text.  STOP 
  8.       2. If X.js is a file, load X.js as JavaScript text.  STOP 
  9.       3... 
  10.       4... 
  11. b. LOAD_AS_DIRECTORY(Y + X) 
  12.       1. If X/package.json is a file, 
  13.          a. Parse X/package.json, and look for "main" field. 
  14.          b. let M = X + (json main field) 
  15.          c. LOAD_AS_FILE(M) 
  16.       2. If X/index.js is a file, load X/index.js as JS text.  STOP 
  17.       3... 
  18.       4... 
  19. 3. LOAD_NODE_MODULES(X, dirname(Y)) 
  20. 4. THROW "not found"  

簡單來說,加載的邏輯或者說優(yōu)先級(jí)為:

  • 優(yōu)先判斷是不是核心模塊
  • 如果不是核心模塊則搜索node_modules
  • 否則在相對(duì)路徑中進(jìn)行搜索

解析之后的文件名可以根據(jù)module對(duì)象或得到: 

  1. // counter-debug.js 
  2.  
  3. console.log(module.filename) // prints absolute path to counter.js 
  4. console.log(__filename) // prints same as above 
  5. // i get: "/Users/laz/repos/medium/modules/counter-debug.js" 
  6.  
  7. let value = 0 
  8.  
  9. module.exports = { 
  10.   increment: () => value++, 
  11.   get: () => value,  

在上述的例子中我們可以看出,解析得到的文件名即使被加載模塊的絕對(duì)路徑。而根據(jù)文件與模塊一一映射的原則,我們可以得出下面兩個(gè)會(huì)破壞模塊導(dǎo)入單例性的特例。

Case Sensitivity

在大小寫敏感的文件系統(tǒng)中或者操作系統(tǒng)中,不同的解析之后的文件可能會(huì)指向相同的文件,但是其緩存鍵名會(huì)不一致,即不同的導(dǎo)入會(huì)生成不同的對(duì)象。 

  1. // app-no-singleton-1.js 
  2. const counter1 = require('./counter.js'
  3. const counter2 = require('./COUNTER.js'
  4.  
  5. counter1.increment() 
  6. console.log(counter1.get()) // prints 1 
  7. console.log(counter2.get()) // prints 0, not same object as counter1 
  8.  
  9. /*  
  10. We have two different resolved filenames: 
  11. - “Users/laz/repos/medium/modules/counter.js” 
  12. - “Users/laz/repos/medium/modules/COUNTER.js” 
  13. */  

在上面的例子中,我們分別用counter、COUNTER這僅僅是大小寫不同的方式導(dǎo)入相同的某個(gè)文件,如果是在某個(gè)大小寫敏感的系統(tǒng)中,譬如UBUNTU中會(huì)直接拋出異常:

 解析為不同的文件名

當(dāng)我們使用require(x)并且x不屬于核心模塊時(shí),其會(huì)自動(dòng)搜索node_modules文件夾。而在npm3之前,項(xiàng)目會(huì)以嵌套的方式安裝依賴。因此當(dāng)我們的項(xiàng)目依賴module-a與module-b,并且module-a與module-b也相互依賴時(shí),其會(huì)生成如下文件路徑格式: 

  1. // npm2 installed dependencies in nested way 
  2. app.js 
  3. package.json 
  4. node_modules/ 
  5. |---module-a/index.js 
  6. |---module-b/index.js 
  7.     |---node_modules 
  8.         |---module-a/index.js  

這樣的話,我們對(duì)于同一個(gè)模塊就有兩個(gè)副本,那當(dāng)我們?cè)趹?yīng)用中導(dǎo)入module-a時(shí),豈會(huì)載入如下文件: 

  1.  // app.js 
  2. const moduleA = require(‘module-a’) 
  3. loads: “/node_modules/module-a/index.js”  

而從module-b中載入module-a時(shí),其載入的是如下文件: 

  1.  // /node_modules/module-b/index.js 
  2. const moduleA = require(‘module-a’) 
  3. loads “/node_modules/module-b/node_modules/module-a/index.js”  

不過在npm3之后,其以扁平化方式進(jìn)行文件加載,其文件目錄結(jié)構(gòu)如下所示: 

  1.  // npm3 flattens secondary dependencies by installing in same folder 
  2. app.js 
  3. package.json 
  4. node_modules/ 
  5. |---module-a/index.js 
  6. |---module-b/index.js  

不過此時(shí)就存在另一個(gè)場景,即我們應(yīng)用本身依賴module-a@v1.1與module-b,而module-b又依賴于module-a@v1.2,在這種情況下還是會(huì)采用類似于npm3之前的嵌套式目錄結(jié)構(gòu)。這樣的話對(duì)于module-a一樣會(huì)產(chǎn)生不同的對(duì)象,不過此時(shí)本身就是不同的文件了,因此相互之間不會(huì)產(chǎn)生沖突。

責(zé)任編輯:龐桂玉 來源: segmentfault
相關(guān)推薦

2024-12-31 11:40:05

2023-12-05 08:20:05

單例模式Python

2022-09-29 08:39:37

架構(gòu)

2013-03-26 10:35:47

Objective-C單例實(shí)現(xiàn)

2015-10-27 09:19:24

2021-09-07 10:44:35

異步單例模式

2023-10-08 10:14:12

2011-06-28 15:18:45

Qt 單例模式

2024-12-03 16:49:58

2023-11-13 16:49:51

C++單例

2019-06-11 09:50:07

SparkBroadcast代碼

2022-02-06 22:30:36

前端設(shè)計(jì)模式

2020-01-09 12:30:20

架構(gòu)運(yùn)維技術(shù)

2021-04-29 07:18:21

Spring IOC容器單例

2021-03-15 07:02:02

java線程安全

2020-05-26 08:04:24

Shell腳本單例

2022-08-10 11:02:56

Python單例模式

2020-05-26 10:28:36

shell腳本單例運(yùn)行

2021-05-29 10:22:49

單例模式版本

2025-06-26 00:40:13

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

亚洲色图25p| 亚洲免费在线观看视频| 国产精品无码专区在线观看 | 久久久久久久久久电影| 国产免费一区二区三区在线能观看| 日本爱爱小视频| 亚洲不卡视频| 日本精品视频一区二区| 成人在线免费观看网址| 日韩av免费观影| 蜜桃在线一区二区三区| 国内精品久久久久影院 日本资源| 国产传媒国产传媒| 福利在线一区| 欧美一区日韩一区| 国产三级日本三级在线播放| 亚洲欧美成人影院| 亚洲国产精品传媒在线观看| 国内不卡一区二区三区| 国产精品亚洲lv粉色| 久久狠狠婷婷| 久久人91精品久久久久久不卡| 欧美精品日韩在线| 色狼人综合干| 亚洲国产精品大全| gogo亚洲国模私拍人体| 国产精品成人国产| 日韩欧美国产高清91| 嫩草影院中文字幕| 菠萝蜜视频国产在线播放| 国产欧美一区二区精品久导航| 波多野结衣精品久久| 亚洲一线在线观看| 日韩高清在线观看| 国产精品av在线| 国产九色在线播放九色| 在线成人av| 欧美高清videos高潮hd| 中文字幕在线有码| 艳女tv在线观看国产一区| 中文欧美日本在线资源| 国产aⅴ激情无码久久久无码| 欧美激情15p| 亚洲国产精彩中文乱码av| 黑人无套内谢中国美女| www.91精品| 这里只有精品免费| 伊人免费视频二| 成人免费观看49www在线观看| 欧美日韩国产a| 天天爽夜夜爽一区二区三区| 少妇精品视频一区二区免费看| 欧美日韩国产精品| 国产美女三级视频| 激情开心成人网| 欧美在线视频不卡| 亚洲国产高清av| 95精品视频| 日韩一卡二卡三卡国产欧美| 国产黑丝在线视频| 给我免费播放日韩视频| 亚洲精品按摩视频| 国产全是老熟女太爽了| 狠狠做深爱婷婷综合一区| 亚洲性生活视频在线观看| 性少妇xx生活| 91成人精品视频| 欧美精品videossex性护士| 国产精品日日夜夜| 翔田千里一区二区| 国产日韩欧美夫妻视频在线观看| 一级特黄色大片| 国产精品亚洲一区二区三区在线 | 日本韩国欧美超级黄在线观看| 日韩禁在线播放| 国产精品密蕾丝袜| 国产精品久久占久久| 精品少妇v888av| 日韩成人高清视频| 日本美女视频一区二区| 97超级碰碰| 色中色在线视频| 中文字幕在线一区| 日韩视频在线视频| www.一区| 亚洲第一中文字幕在线观看| 国精产品一区一区三区免费视频| 第一sis亚洲原创| 久久91精品国产91久久跳| 天海翼一区二区| 蜜桃久久av一区| 91在线精品观看| 欧美美乳在线| 亚洲伦在线观看| 日日鲁鲁鲁夜夜爽爽狠狠视频97| 精品福利在线| 精品剧情在线观看| 国产极品视频在线观看| 精品69视频一区二区三区Q| 国产精品都在这里| 欧美 日韩 国产 成人 在线 91 | 另类激情视频| 欧美不卡激情三级在线观看| 人妻少妇一区二区| 欧美久久视频| 国产欧美一区二区三区在线| 亚洲欧美强伦一区二区| 国产精品视频一二三| 国产精品入口芒果| 91麻豆精品国产综合久久久 | 亚洲片国产一区一级在线观看| 日本不卡一二区| 欧美专区一区二区三区| 成人av蜜桃| 欧美另类极品| 在线看一区二区| 黄色av网址在线观看| 97精品国产一区二区三区| 欧美在线一级va免费观看| 国内老熟妇对白hdxxxx| 中文欧美字幕免费| 精品视频无码一区二区三区| 久草在线综合| 欧美极品少妇xxxxx| 国产精品国产三级国产普通话对白| 久久免费偷拍视频| 成熟丰满熟妇高潮xxxxx视频| 精品国产亚洲日本| 日韩中文在线中文网在线观看| 久久中文字幕免费| av电影在线观看完整版一区二区| 欧美日韩dvd| 久久丁香四色| 久久在线观看视频| 97人妻一区二区精品免费视频| 国产无人区一区二区三区| 99热在线这里只有精品| 加勒比视频一区| 久久久亚洲国产| 亚洲黄色在线观看视频| 亚洲精品中文在线影院| 波多野结衣免费观看| 国产精品毛片久久| 91久久精品在线| 黄色网页在线播放| 欧美日本韩国一区| 国产一二三四区| 国产精品影视网| 国产精品日韩三级| 国产精品15p| 欧洲一区二区视频| 国产乱理伦片a级在线观看| 欧洲国产伦久久久久久久| 色欲AV无码精品一区二区久久 | 91午夜理伦私人影院| 国产在线高清视频| 日韩视频123| 日韩成人一区二区三区| 91免费看视频| 国产高潮免费视频| 我不卡伦不卡影院| 成人在线观看av| 女人让男人操自己视频在线观看| 精品亚洲aⅴ在线观看| 青青视频在线免费观看| 国产欧美一区二区精品性| 亚洲小视频网站| 韩国av一区| 久久综合伊人77777麻豆| 日韩欧美一区二区三区在线观看| 亚洲午夜久久久影院| 中文字幕在线2018| 亚洲一区在线视频观看| 亚洲制服丝袜在线播放| 日本不卡一区二区三区高清视频| 亚洲欧美在线网| 99精品国产一区二区三区2021 | 欧美黄色成人| 久久久女人电视剧免费播放下载| 亚洲av成人精品一区二区三区在线播放 | 波多野结衣视频观看| 自拍偷自拍亚洲精品播放| 性活交片大全免费看| 日韩精品亚洲一区| 亚洲一区 在线播放| 天天躁日日躁狠狠躁欧美| 国产欧美精品xxxx另类| a√中文在线观看| 中文字幕亚洲欧美日韩在线不卡 | 久久亚洲精品人成综合网| 欧美精品免费在线| 日韩av高清在线| 日韩欧美一区在线观看| 99re这里只有精品在线| 亚洲欧美激情视频在线观看一区二区三区 | 小明成人免费视频一区| 欧美激情亚洲综合一区| 最近高清中文在线字幕在线观看| 精品久久久网站| 亚洲天堂手机在线| 高跟丝袜一区二区三区| 久久国产美女视频| 国产欧美日本一区视频| 催眠调教后宫乱淫校园| 久久精品国产免费| 男人天堂网视频| 韩国av一区| 成人免费看片视频在线观看| 深爱激情综合| 久久久久久久久久久久久9999| 97精品资源在线观看| 国产成人在线一区二区| 9999在线视频| 欧美成年人在线观看| 在线观看黄色av| 亚洲片国产一区一级在线观看| 免费看日韩av| 日韩欧美国产一区在线观看| 在线观看一二三区| 日本韩国欧美一区| www亚洲视频| 精品福利一区二区| 国产真实夫妇交换视频| 亚洲美女免费在线| 国产美女久久久久久| 中文字幕av一区二区三区| 3d动漫精品啪啪一区二区下载| 成人手机电影网| wwwww在线观看| 国产成人日日夜夜| 一起草最新网址| 国产一区二区不卡在线| www欧美激情| 青青草国产精品97视觉盛宴| 黑人糟蹋人妻hd中文字幕| 99国产一区| 国产 福利 在线| 久久精品天堂| 精品久久久久久久免费人妻| 亚洲在线成人| 久草在在线视频| 日韩精品久久久久久| 超碰影院在线观看| 日本中文在线一区| 国产色视频在线播放| 另类小说一区二区三区| 亚洲最大天堂网| 国产精品一级片| 中国特级黄色大片| 91蜜桃视频在线| 欧美激情 一区| 亚洲天堂福利av| 久久网中文字幕| 黄网站色欧美视频| 一级做a爰片久久毛片| 欧美伊人精品成人久久综合97 | 久久久久久久久精| 亚洲成人久久影院| 免费看污视频的网站| 欧美主播一区二区三区美女| 中文在线观看免费高清| 欧美日精品一区视频| 国产老女人乱淫免费| 欧美xxx久久| 欧美孕妇孕交| 日韩在线观看成人| 国产美女情趣调教h一区二区| 久久久免费观看| avav成人| 成人av网站观看| 美女亚洲一区| 国产av不卡一区二区| 亚洲国产清纯| 国产一级做a爰片久久| 国产一区二区精品久久| 国产福利在线观看视频| 国产欧美精品一区| 精品99久久久久成人网站免费| 午夜久久久久久久久久一区二区| av久久网站| 在线视频你懂得一区| 69av视频在线观看| 欧美二区在线观看| 国产18精品乱码免费看| 亚洲男人天堂视频| 国产精品扒开做爽爽爽的视频| 国内精品伊人久久| 成人涩涩视频| 国产精品久久亚洲| 日韩成人免费| 日韩亚洲欧美视频| 奇米在线7777在线精品| 性生交大片免费看l| 久久九九久精品国产免费直播| 日韩在线观看视频一区二区| 岛国av一区二区在线在线观看| 亚洲天堂免费av| 蜜臀久久久久久久| 91手机视频在线观看| 五月激激激综合网色播| 亚洲小说欧美另类激情| 一区二区日本视频| 日韩精品xxx| 中文字幕在线一区| 波多野结衣在线观看一区| 精品成人一区二区三区| 在线免费看黄| 国产成人综合av| 国产美女撒尿一区二区| 黄色免费高清视频| 日韩电影在线免费| 中文字幕在线播放视频| 亚洲啪啪综合av一区二区三区| 丁香六月婷婷综合| 精品国产三级电影在线观看| 视频三区在线| 国产精品久久久久久久久久东京| 都市激情亚洲欧美| 日产精品久久久久久久蜜臀| 日产欧产美韩系列久久99| 亚洲国产第一区| 亚洲一区视频在线| 国产女人18毛片水真多| 中文字幕一精品亚洲无线一区| 小视频免费在线观看| 国产精品视频入口| 99久久精品网| 亚欧激情乱码久久久久久久久| 久久婷婷国产综合精品青草| 日韩久久精品视频| 亚洲国产高清高潮精品美女| 欧美videos另类精品| 97se在线视频| 欧美精品1区| 人妻av一区二区三区| 亚洲黄一区二区三区| 国产欧美久久久精品免费| 精品国产欧美成人夜夜嗨| 国内欧美日韩| 一本—道久久a久久精品蜜桃| 另类中文字幕网| 三级黄色在线观看| 欧美一区二视频| а√中文在线8| 96国产粉嫩美女| 欧美不卡在线| 久久免费精品国产| 午夜欧美在线一二页| 日本亚洲欧美| 国产精品99久久久久久白浆小说 | 亚洲图片在线观看| 国内精品视频一区二区三区八戒| 久久爱一区二区| 日韩欧美不卡一区| 91av久久| 免费99视频| 久草这里只有精品视频| 青青操视频在线播放| 亚洲第一精品夜夜躁人人爽| 国模私拍一区二区国模曼安| 美日韩精品免费| 蜜臀av一区二区在线免费观看| 天天色天天综合| 欧美mv日韩mv国产网站| 欧美13videosex性极品| 欧美精品一区二区三区在线四季| 日本sm残虐另类| 日本aⅴ在线观看| 亚洲精品ady| 国产精品久久久久77777丨| 久久精品免费观看| 91成人精品一区二区| 91精品午夜视频| av中文在线资源| 日本不卡一区二区三区视频| 蜜桃视频在线一区| 久久久美女视频| 亚洲三级黄色在线观看| 91麻豆精品国产综合久久久| 精品国产一区二区三区无码| 91视频精品在这里| 在线播放一级片| 高清欧美一区二区三区| 国产videos久久| 亚洲熟女乱综合一区二区| 欧美性猛交xxxx乱大交极品| 女女色综合影院| 久久99影院| 国产精品亚洲а∨天堂免在线| 日本在线播放视频| 另类图片亚洲另类| 深爱激情久久| 精品1卡二卡三卡四卡老狼| 91久久精品一区二区三区| a级毛片免费观看在线| 欧美影视一区二区| 国产成人午夜电影网| 最近中文字幕av| 91超碰caoporn97人人| 女人天堂亚洲aⅴ在线观看|