web-dev-qa-db-ja.com

ノードモジュールは相互に必要ですか?

私は次の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の「newUser()」からTypeErrorが発生します。 room.jsのユーザーはindex.jsのユーザーによって隠されているようです。

私は何か間違ったことをしていますか?この種の要求は許可されていますか?何か案は?ありがとう。

25
Ziyu

これがノードでどのように処理されるかについては、 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();
var room = new Room();

このように、エクスポートは必要な時間によって定義されます。

しかし、一般的に、循環依存関係がある場合は、何か間違ったことをしているので、アーキテクチャについて考える必要があります。 Userが新しいRoomsを作成する必要があり、Roomが新しいUsersを作成する必要がある場合、どちらも責任が大きすぎるようです。おそらく、適切なインスタンスを作成してRoomUserに直接インスタンス化するのではなく、それらを渡すことを担当する3番目のコンポーネントが必要になるでしょう。

27

私はそれを行う方法がはるかに良いと思います。エクスポートを切り替えて、次のように要求するだけです。

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

12
balicekt

違い:

/* code above */
function a() {};

そして

/* code above */
var a = function () {};

最初の例では、afunctionすでにcode aboveにありますが、2番目の例ではそうではありません。

この簡単な解決策にたどり着くことができることを理解したら、次のようにします。

// user.js

module.exports = User;

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

// room.js

module.exports = Room;

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

// index.js

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

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