偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Node.js的循環(huán)依賴

開發(fā) 前端
循環(huán)依賴,簡單點來說就是a文件中require b文件,然后b文件中又反過來require a文件。這個問題我們平時可能并不大注意到,但如果處理不好可能會引起一些讓人摸不清的問題。在node中,是如何處理循環(huán)依賴的問題的呢?

循環(huán)依賴,簡單點來說就是a文件中require b文件,然后b文件中又反過來require a文件。這個問題我們平時可能并不大注意到,但如果處理不好可能會引起一些讓人摸不清的問題。在node中,是如何處理循環(huán)依賴的問題的呢?

51CTO推薦專題:Node.js專區(qū)

寫個簡單的例子來試驗一下看吧。

定義兩個文件:

a.js

  1. var b = require('./b');  
  2. console.log('a.js get b:' + b.b);  
  3. module.exports.a = 1; 

b.js

  1. var a = require('./a');  
  2. console.log('b.js get a:' + a.a);  
  3. module.exports.b = 2; 

執(zhí)行

node a.js

輸出的結(jié)果是

b.js get a:undefined

a.js get b:2

從打印的軌跡上來看,代碼執(zhí)行的流程大致如下:

  1. a.js:                               b.js:  
  2.  
  3. var b = require('./b');  
  4.  
  5.                                     var a = require('./a'); // a = {}  
  6.  
  7.                                     console.log('b.js get a:' + a.a);  
  8.  
  9.                                     module.exports.b = 2;  
  10.  
  11. // b = {b: 2}  
  12.  
  13. console.log('a.js get b:' + b.b);  
  14.  
  15. module.exports.a = 1; 

node的加載過程,可以在lib/module.js文件中找到。與這個過程相關(guān)的代碼主要集中在Module._load方法里。可以看到,node會為每個新加載的文件創(chuàng)建一個Module對象(假設(shè)為a),這個就是我們在a.js代碼中看到的module了。在創(chuàng)建a之后,node會先將a放到cache中,然后再對它進(jìn)行加載操作。也就是說,如果在加載a的過程中,有其他的代碼(假設(shè)為b)require a.js的話,那么b可以從cache中直接取到a的module,從而不會引起重復(fù)加載的死循環(huán)。但帶來的代價就是在load過程中,b看到的是不完整的a,也就是為什么前面打印undefined的原因。

Module的構(gòu)造函數(shù)

  1. function Module(id, parent) {  
  2.   this.id = id;  
  3.   this.exports = {};  
  4.   this.parent = parent;  
  5.   this.filename = null;  
  6.   this.loaded = false;  
  7.   this.exited = false;  
  8.   this.children = [];  

Module._load方法

  1. Module._load = function(request, parent, isMain) {  
  2.   //...  
  3.   var module = new Module(id, parent);  
  4.   //...  
  5.   Module._cache[filename] = module;  
  6.   try {  
  7.     module.load(filename);  
  8.   } catch (err) {  
  9.     delete Module._cache[filename];  
  10.     throw err;  
  11.   }  
  12.   return module.exports;  
  13. }; 

這個看似簡單粗暴的處理手法,但實際上是node作者權(quán)衡各方面因素的結(jié)果。我們敬愛的npm作者issacs強調(diào)說了,這不是bug,而且近期內(nèi)不會做什么改變。當(dāng)然,issacs也給出了一些規(guī)避這個陷阱的建議(具體可以參考后面給的鏈接[1])。我總結(jié)了一下,主要有兩點:一個是在造成循環(huán)依賴的require之前把需要的東西exports出去;另一個是不要在load過程中操作未完成的模塊。

所以上面的例子的一種處理方法就是把各自的exports語句放到require語句前面,然后再運行,可以看到打印了正確的值。

從前面的分析來看,循環(huán)依賴的陷阱出現(xiàn)的條件比較苛刻:一個是循環(huán)依賴,另一個是在load期間調(diào)用未加載完成的對象。所以大家平常不怎么會遇到。但我之前就曾華麗麗的邂逅了這個陷阱,在這里拿出來當(dāng)一下反面教材。。。

場景簡化后大致如下:我有一堆service,每一個service負(fù)責(zé)消費某一類消息,并且可能會產(chǎn)生新的消息給其他service消費。從消息傳遞上來看,并沒有產(chǎn)生循環(huán)依賴。但我為了解耦,定義了一個消息中心center的角色出來進(jìn)行消息分發(fā)。center主要是維護一個type -> service的map來路由消息,這樣center就得把所有的service加載進(jìn)來,于是產(chǎn)生了center->service的依賴。另一面,每個service又需要通過center來分發(fā)它們新產(chǎn)生的消息,于是又出現(xiàn)了service->center的依賴,循環(huán)依賴就這么出來了。剛好在service加載的過程中,又調(diào)用了center的一個方法,就發(fā)生了undefined的錯誤。

這個問題查清楚原因以后,解決起來并不困難。

一種方法就是按前面的方法,在代碼層面上規(guī)避循環(huán)依賴的陷阱;

另外也可以在設(shè)計的層面上徹底避免循環(huán)依賴的出現(xiàn)。我的場景之所以出現(xiàn)循環(huán)依賴,是因為center和service都需要知道對方的存在,即 center <- -> service。如果采用依賴注入的方式,則可以切斷這種直接依賴,類似于center <- container -> service。即加入一個container角色,把center和service都先加載進(jìn)來,然后再用IOC的方法把依賴關(guān)系建立好。這樣center和service都無須知道對方具體的文件所在了,也就不會循環(huán)的require對方了。

總的來說,循環(huán)依賴的陷阱并不大容易出現(xiàn),但一旦出現(xiàn)了,在實際的代碼中也許還真不好定位。它的存在給我們提了個醒,注意你工程中的依賴關(guān)系。哪天node對你抱怨,一個你明明已經(jīng)exports了的方法undefined,我們就該提醒一下自己:哦,也許是它來了:)

原文:http://club.cnodejs.org/topic/4f16442ccae1f4aa27001045

【編輯推薦】

  1. 用Eclipse調(diào)試Node.js代碼
  2. 用Web socket和Node.js實現(xiàn)HTML 5畫布的實時繪圖
  3. Node.js后端框架設(shè)計構(gòu)想
  4. 走近Node.js的異步代碼設(shè)計
  5. 使用Node.js開發(fā)多人玩的HTML 5游戲
責(zé)任編輯:陳貽新 來源: CNode
相關(guān)推薦

2021-05-27 09:00:00

Node.js開發(fā)線程

2024-01-05 08:49:15

Node.js異步編程

2011-09-08 14:16:12

Node.js

2021-12-18 07:42:15

Ebpf 監(jiān)控 Node.js

2023-01-31 16:43:31

?Node.js事件循環(huán)

2015-03-10 10:59:18

Node.js開發(fā)指南基礎(chǔ)介紹

2013-11-01 09:34:56

Node.js技術(shù)

2021-12-25 22:29:57

Node.js 微任務(wù)處理事件循環(huán)

2020-05-29 15:33:28

Node.js框架JavaScript

2011-09-08 13:46:14

node.js

2011-11-01 10:30:36

Node.js

2011-09-02 14:47:48

Node

2011-09-09 14:23:13

Node.js

2011-11-10 08:55:00

Node.js

2012-10-24 14:56:30

IBMdw

2021-10-22 08:29:14

JavaScript事件循環(huán)

2021-09-26 05:06:04

Node.js模塊機制

2021-11-06 18:40:27

js底層模塊

2011-11-02 09:04:15

Node.js

2019-07-09 14:50:15

Node.js前端工具
點贊
收藏

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