精品欧美一区二区三区在线观看 _久久久久国色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)

欧美激情xxxx性bbbb| 欧美色道久久88综合亚洲精品| 成人黄色av播放免费| 永久久久久久久| 日韩精品亚洲aⅴ在线影院| 欧美在线观看一二区| 2021狠狠干| 肉丝一区二区| 狠狠色丁香婷婷综合久久片| 国内精品久久久久影院 日本资源| 人妻av无码一区二区三区 | 免费a在线观看| 久久9热精品视频| 91国语精品自产拍在线观看性色| 精品手机在线视频| 精品少妇一区| 91精品国产一区二区三区香蕉| 国产美女网站在线观看| 少妇av一区二区三区无码| 日韩av三级在线| 岛国在线视频| www.欧美日韩| 91最新在线免费观看| 黑人精品无码一区二区三区AV| 亚洲精品中文字幕乱码| 亚洲一区二区久久| 亚洲少妇18p| 日本一区二区三区电影免费观看| 色噜噜狠狠成人网p站| 一本久道高清无码视频| 国产在线看片| 中文字幕精品—区二区四季| 精品一区二区不卡| av中文字幕观看| 日韩福利电影在线| 欧美亚洲视频一区二区| 精品视频在线看| 亚洲免费精品视频| 久久精品a一级国产免视看成人| 国产成人免费视频一区| 国产伊人精品在线| 一区二区三区免费观看视频| 日韩专区欧美专区| 日韩免费在线视频| 中文字幕免费在线观看视频| 日韩视频在线一区二区三区 | 欧美视频在线一区| av网站手机在线观看| 中国av在线播放| 亚洲精品高清在线| 四虎精品欧美一区二区免费| 国产网友自拍视频导航网站在线观看 | 午夜av一区二区| 激情小视频网站| 福利写真视频网站在线| 亚洲国产aⅴ天堂久久| 69精品丰满人妻无码视频a片| av片在线观看免费| 亚洲综合精品自拍| 欧美系列日韩一区| 精品在线不卡| 三级在线观看| 91视频免费观看| 蜜桃传媒视频第一区入口在线看| 亚洲欧美日韩免费| 26uuu国产在线精品一区二区| 久久国产一区| 可以在线观看的黄色| 久久久久国色av免费看影院| 欧美精品免费观看二区| www.av在线| 亚洲欧美偷拍另类a∨色屁股| 国产成人精品免费看在线播放 | 丰满少妇在线观看| 国产精品高潮久久| 91精品国产免费| 韩国黄色一级片| 欧美三级午夜理伦三级小说| 亚洲欧美一区二区激情| 18精品爽国产三级网站| 午夜片欧美伦| 久久免费高清视频| 一二三区免费视频| 国内精品国产成人| 亚洲欧美国产视频| 国产精华一区二区三区| 好吊色在线观看| 久久免费午夜影院| 艳母动漫在线免费观看| 国产高清视频色在线www| 色综合中文字幕国产| 一级在线免费视频| 超碰cao国产精品一区二区| 亚洲老头同性xxxxx| 中文国语毛片高清视频| 亚洲片区在线| 国产狼人综合免费视频| 丁香花免费高清完整在线播放| 91毛片在线观看| 国产成年人在线观看| 久久青草伊人| 在线成人av网站| 亚洲一级av无码毛片精品| 日韩精品免费一区二区在线观看| 欧美精品在线看| 黄色片视频免费| 国产成人午夜精品影院观看视频 | 欧美精品网站| 国产精品久久不能| 少妇高潮毛片色欲ava片| 亚洲视频在线免费播放| eeuss鲁片一区二区三区在线观看| 色之综合天天综合色天天棕色| 日韩电影免费观看| 欧美无人高清视频在线观看| 日韩www视频| 欧美fxxxxxx另类| 国产精自产拍久久久久久| 亚洲精品无遮挡| 综合久久综合久久| 日韩大片一区二区| 国产亚洲一区二区三区啪| 欧美激情一区二区久久久| 亚洲视频久久久| 久久先锋影音av鲁色资源网| 日本中文字幕亚洲| 95精品视频| 在线观看国产成人av片| 国产精品乱子伦| 成人精品视频.| 水蜜桃在线免费观看| 欧美男男gaygay1069| 亚洲色图激情小说| 伊人中文字幕在线观看| 91视频一区二区三区| 国精产品一区一区三区视频| 亚洲精品影片| 欧美激情xxxxx| 亚洲精品字幕在线| 男人的天堂在线视频免费观看| av资源网一区| 夜夜添无码一区二区三区| 欧洲大片精品免费永久看nba| 日韩中文字幕免费视频| 中文字幕乱码视频| 国产精品久久久久久久蜜臀| 天堂av在线网站| 成人羞羞视频播放网站| 国产精品视频一| 在线观看精品一区二区三区| 欧美视频一区在线观看| 在线观看天堂av| 韩国三级电影一区二区| 中文字幕一区二区三区乱码| 9999精品免费视频| 欧美成人一二三| 黄色福利在线观看| 精品久久久精品| 国产高清自拍视频| 日韩激情av在线| 一区二区日本| 欧美二区观看| 久久九九国产精品怡红院 | 久久久久久久久久91| 成人午夜免费av| 精品少妇人妻av免费久久洗澡| 成人性生交大片免费看中文视频 | av黄色在线| 91精品在线麻豆| 青娱乐国产盛宴| 99免费精品视频| 黄色免费观看视频网站| 日本一区二区免费高清| 91视频免费在线| a'aaa级片在线观看| 亚洲美女免费精品视频在线观看| 国产真人无遮挡作爱免费视频| 国产精品久久久久影院老司| 日本网站在线看| 野花国产精品入口| 天堂社区 天堂综合网 天堂资源最新版| 精品国产美女a久久9999| 另类视频在线观看| 天天操天天干天天干| 欧美午夜精品久久久久久孕妇| 少妇高潮一区二区三区喷水| 成人免费毛片嘿嘿连载视频| 白嫩少妇丰满一区二区| 亚洲第一天堂| 久久久久欧美| 亚洲日本中文| 青草成人免费视频| 国产黄网站在线观看| 日韩精品视频免费| 国产精品污视频| 亚洲成人动漫av| 日本成人免费在线观看| 成人午夜免费av| 亚洲综合欧美激情| 国产乱国产乱老熟| 国产盗摄女厕一区二区三区| 国产无套内射久久久国产| 亚洲中无吗在线| 欧美日韩免费精品| 日韩一级淫片| 国产伦精品免费视频| 台湾佬中文娱乐网欧美电影| 美日韩精品免费观看视频| 牛牛热在线视频| 欧美精品一区二区三区高清aⅴ| 制服丝袜在线一区| 精品人伦一区二区三区蜜桃网站| 天天色影综合网| 久久久久久99久久久精品网站| 99热这里只有精品2| 日产国产欧美视频一区精品| 91午夜在线观看| 99精品网站| 日韩精品久久久免费观看| 国产乱人伦精品一区| 亚洲综合小说区| 欧美美女福利视频| 国产精品第3页| 欧美第一视频| 91高清视频免费| av有码在线观看| 欧美国产精品人人做人人爱| 麻豆视频在线免费观看| 中文亚洲视频在线| 精品视频三区| 亚洲日本中文字幕免费在线不卡| 欧日韩在线视频| 欧美成人精品福利| 九9re精品视频在线观看re6 | 久久久久久国产精品久久| 免费高清完整在线观看| 中文字幕在线精品| av在线免费播放网站| 亚洲日本成人女熟在线观看 | 久热精品在线视频| 蜜桃视频网站在线| 色老头一区二区三区在线观看| 欧美午夜黄色| 亚洲欧美日韩第一区| 亚洲日本国产精品| 国产丝袜一区二区三区免费视频| 日韩一区二区三区在线观看视频| 精品福利一区二区三区| 成 人片 黄 色 大 片| 欧美va亚洲va| 蜜臀av免费在线观看| 亚洲国产成人精品久久久国产成人一区 | 制服.丝袜.亚洲.中文.综合| 久久免费视频3| 精品欧美日韩精品| 国产精品视频精品| 国产一区高清| 国产中文字幕亚洲| 久久伊人精品| 国产精品一区二区三区在线| 成人性生交大片免费看中文视频| 国产在线精品一区二区三区》 | 麻豆国产91在线播放| xxxx在线免费观看| 国产suv精品一区二区6| 午夜免费福利影院| 久久久综合视频| 天堂网av2018| 亚洲一卡二卡三卡四卡无卡久久| 亚洲精品www久久久久久| 色天使久久综合网天天| 91精品中文字幕| 精品国产91乱码一区二区三区| 青青草免费在线| 色先锋资源久久综合5566| 中文字幕中文字幕在线中高清免费版| 欧美国产日韩一区二区三区| 两个人看的在线视频www| 国产精品精品久久久久久| 国产精品亚洲欧美一级在线 | 91精品亚洲| 国产精品一区二区免费在线观看| 日韩高清在线观看| 日本少妇xxx| 成人激情视频网站| 欧美18—19性高清hd4k| 亚洲精品国产精华液| 天天综合网久久综合网| 欧洲一区二区三区在线| 亚洲av无码片一区二区三区| 亚洲精品一区久久久久久| 成人在线直播| 日韩免费视频在线观看| 日韩欧美高清一区二区三区| 欧美日韩免费观看一区| 国内精品久久久久久久影视蜜臀| 好男人www社区| 乱插在线www| 欧美撒尿777hd撒尿| 国产成人精品毛片| 亚洲欧美一区二区三区四区| 黄色网页在线观看| 国产成+人+综合+亚洲欧美丁香花| 欧美日本三级| 亚洲v欧美v另类v综合v日韩v| 国产精品porn| 污视频免费在线观看网站| 成人av动漫在线| 欧美国产日韩在线观看成人 | 欧美视频在线播放一区| 国产在线观看免费一区| 国产熟妇久久777777| 一个色综合av| 国产精品久久久久久无人区| 亚洲另类欧美自拍| av剧情在线观看| 91成人在线看| 婷婷丁香综合| 色婷婷狠狠18| 国产午夜精品一区二区| 色播视频在线播放| 欧美第一区第二区| av片在线观看免费| 成人a在线观看| 成人免费在线播放| 亚洲免费av一区二区三区| caoporn国产精品| 妺妺窝人体色www聚色窝仙踪| 欧美群妇大交群的观看方式| 福利在线播放| 日本成人黄色片| 亚洲调教一区| 亚洲熟妇av一区二区三区漫画| 成人h动漫精品一区二| 久久久99精品| 欧美一级午夜免费电影| 95视频在线观看| 66久久国产| 亚洲综合婷婷久久| 国产精品嫩草影院av蜜臀| 黄色av一区二区| 亚洲网站在线看| 成人涩涩视频| 亚洲精品一区二区三区樱花| 日韩高清不卡一区二区三区| 法国空姐电影在线观看| 色嗨嗨av一区二区三区| 国自产拍在线网站网址视频| 欧美壮男野外gaytube| 久久99精品久久久久久园产越南| 2022亚洲天堂| 国产亚洲成aⅴ人片在线观看 | 婷婷丁香综合网| 欧美日韩极品在线观看一区| 日本中文字幕伦在线观看| 91日本视频在线| 好看的av在线不卡观看| 中国极品少妇xxxx| 日韩欧美在线观看视频| 精品视频一二三| 成人网在线视频| 精品1区2区3区4区| 国产精品无码永久免费不卡| 在线亚洲+欧美+日本专区| 欧美日本一道| 91欧美日韩一区| 亚洲国产影院| 99久久精品免费视频| 在线不卡a资源高清| 黄色在线观看视频网站| 精品视频免费观看| 男人的天堂亚洲一区| 国产精品视频一区二区三| 精品sm在线观看| 欧美激情喷水| 一级黄色录像免费看| 成人免费视频视频| 日韩欧美国产另类| 久久精品夜色噜噜亚洲aⅴ| 久久久久亚洲AV成人无在| 91精品国产日韩91久久久久久| 阿v视频在线观看| 日本成人三级| 国产福利精品导航| 中文字幕免费观看| 久热精品视频在线| 亚欧日韩另类中文欧美| 中文字幕在线视频精品| 亚洲va欧美va人人爽| 91电影在线播放| 国产一区二区中文字幕免费看| 免费高清不卡av| 中文字幕一区二区三区精品| xxav国产精品美女主播| 欧美1区2区3区4区| 91福利免费观看| 日韩欧美亚洲范冰冰与中字| 在线免费观看a视频| 欧美一区二区三区四区夜夜大片| 国产一区二区看久久|