2014-04-28 103 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()'扔进一些曾经工作的代码中。我没有花时间去寻找根本原因,但要小心..(这个'未定义是传递成员函数作为参数时唯一确定的症状)。我喜欢这种方法,但那又是浪费时间...... –