2014-04-28 101 views
15

我有以下3個文件。節點模塊是否需要對方

user.js需要room.js和room.js需要user.js。

user.js的

var Room = require('./room.js'); 

var User = function() {}; 
User.prototype.test = function() { 
    return new Room(); 
}; 

module.exports = User; 

room.js

var User = require('./user.js'); 

var Room = function() {}; 
Room.prototype.test = function() { 
    return new User(); 
}; 

module.exports = Room; 

index.js

var User = require('./user.js'); 
var Room = require('./room.js'); 

var user = new User(); 
var room = new Room(); 

user.test(); 
room.test(); 

index.js既需要室和用戶。

這是問題所在。當我運行index.js時,我會在room.js中從'new User()'中得到TypeError。似乎用戶在room.js中被用戶隱藏在index.js中。

難道我做錯了什麼?這種要求是否允許?有任何想法嗎?謝謝。

回答

17

檢查出http://nodejs.org/api/modules.html#modules_cycles這是如何在節點中處理的。

可以解決你在幾個方面,例如在依賴傳遞給實例又名依賴注入

// user.js 
var User = function (Room) { this.Room = Room; }; 
User.prototype.test = function() { 
    return new this.Room(); 
}; 
module.exports = User; 

// room.js 
var Room = function (User) { this.User = User; }; 
Room.prototype.test = function() { 
    return new this.User(); 
}; 
module.exports = Room; 

// index.js 
var User = require('./user.js'); 
var Room = require('./room.js'); 

var user = new User(Room); 
var room = new Room(User); 

另一種方法是,只需要文件時,你需要他們

// user.js 
var User = function() {}; 
User.prototype.test = function() { 
    var Room = require('./room'); 
    return new Room(); 
}; 
module.exports = User; 


// room.js 
var Room = function() {}; 
Room.prototype.test = function() { 
    var User = require('./user'); 
    return new User(); 
}; 
module.exports = Room; 

// index.js 
var User = require('./user.js'); 
var Room = require('./room.js'); 

var user = new User(Room); 
var room = new Room(User); 

像這樣,您的出口是根據您需要的時間來定義的。但是一般來說,如果你有循環依賴,那麼你做錯了什麼,應該考慮一下你的架構。 如果User需要創建新的RoomsRoom需要創建新的Users,看起來他們都有太多的責任。 可能您需要第三個組件負責創建正確的實例並將它們傳遞給RoomUser,而不是讓它們直接實例化這些實例。

+0

很好的答案。謝謝。重構架構似乎是最好的選擇:) – Ziyu

8

我認爲有更好的方法如何做到這一點。只需切換出口,需要這樣的:

user.js的

var User = function() {}; 
module.exports = User;  

User.prototype.test = function() { 
    return new Room(); 
}; 

var Room = require('./room.js'); 

room.js

var Room = function() {}; 
module.exports = Room;  

Room.prototype.test = function() { 
    return new User(); 
}; 

var User = require('./user.js'); 

index.js

var User = require('./user.js'); 
var Room = require('./room.js'); 

var user = new User(); 
var room = new Room(); 

user.test(); 
room.test(); 

檢查這篇文章:https://coderwall.com/p/myzvmg/circular-dependencies-in-node-js

+0

哇!自www創建以來,這是我見過的最天才的事情,這應該是正確的答案,謝謝 –

+0

這似乎是一個很好的答案,但我重構了代碼從構造方法到這個方法,我有把一個貌似沒用的'bind()'扔進一些曾經工作的代碼中。我沒有花時間去尋找根本原因,但要小心..(這個'未定義是傳遞成員函數作爲參數時唯一確定的症狀)。我喜歡這種方法,但那又是浪費時間...... –