【问题标题】:NodeJS some modules not workingNodeJS 一些模块不工作
【发布时间】:2016-01-17 19:33:17
【问题描述】:

我正在用 socket.io 和 nodejs 制作一个游戏,我正在制作一个名为 rooms.js 的模块,这个模块需要 users.js 模块和 fiveSocket.js 模块 但是当我从主服务器文件调用Rooms.New 时,它说fiveSocket 未定义,当Rooms.New 调用users.js 函数时,同样的问题,我得到TypeError: Cannot read property 'getSocketIDbyId' of undefined

rooms.js:

var mysql   = require('../mysql/mysql.js');
var headers = require('./headers.js');
var users   = require('./users.js');
var fiveSocket = require('./sockets.js');
var Rooms = {
    Obj: {},
    Room: function(data) {
        var room = this;
        this.name = data.name;
        this.users = [];
        this.floorCode = data.floor;
        this.description = data.desc;
        this.maxUsers = data.maxUsers;
        this.owner = data.owner;
        this.setTime = new Date().getTime();
        this.dbID = data.dbID;
        this.doorx = data.doorx;
        this.doory = data.doory;
        this.doordir = data.doordir;
    },
    New: function(socketID, roomID) {
        var keys      = Object.keys(Rooms.Obj).length;
        var id        = keys + 1;
        var callback  = function(row) {
            fiveSocket.emitClient(socketID, headers.roomData, {
                title: row.title,
                desc: row.description,
                mapStr: row.floorCode,
                doorx: row.doorx,
                doory: row.doory,
                doordir: row.doordir
            });
            var uid = users.getIdBySocketID(socketID);
            users.Obj[uid].curRoom = roomID;
            var rid = Rooms.getIdByDbID(roomID);
            Rooms.Obj[rid].users.push(uid);
        }
        if(Rooms.getIdByDbID(roomID) != false) {
            var room = Rooms.getIdByDbID(roomID);
            var row = { title: room.name, description: room.description, floorCode: room.foorCode, doorx: room.doorx, doory: room.doory, doordir: room.doordir };
            callback(row);
        } else {
            mysql.Query('SELECT * FROM rooms WHERE id = ? LIMIT 1', roomID, function(rows) {
                if(rows.length > 0) {
                    var row = rows[0];
                    Rooms.Obj[id] = new Rooms.Room({name: row.title, floorCode: row.floorCode, desc: row.description, maxUsers: row.maxUsers, owner: row.owner, dbID: row.id, doorx: row.doorx, doory: row.doory, doordir: row.doordir});
                    callback(row);
                }
            });
        }
    },
    removeUser: function(DBroomID, userID) {
        var rid = Rooms.getIdByDbID(DBroomID);
        var room = Rooms.Obj[rid];
        var index = room.indexOf(userID);
        if (index > -1) array.splice(index, 1);
    },
    Listener: function(users) {
        setInterval(function(){
            for(var roomID in Rooms.Obj) {
                var room = Rooms.Obj[roomID];
                // send users coordinates 
                room.users.forEach(function(uid) {
                    var socketID = users.getSocketIDbyId(uid);
                    var data = Rooms.getUsersInRoomData(roomID);
                    fiveSocket.emitClient(socketID, headers.roomUsers, data);
                });
                // unload inactive rooms (no users after 10 seconds)
                var activeUsers = room.users.length;
                var timestamp = room.setTime;
                var t = new Date(); t.setSeconds(t.getSeconds() + 10);
                var time2 = t.getTime();
                if(activeUsers <= 0 && timestamp < time2) {
                    Rooms.Remove(roomID);
                }
            }
        }, 1);
    },
    getUsersInRoomData: function(roomID) {
        var room = Rooms.Obj[roomID];
        var obj = {};
        room.users.forEach(function(uid) {
            var user = users.Obj[uid];  
            obj[uid] = {
                username: user.username,
                position: user.position,
                figure: user.figure
            };
        });
        return obj;
    },
    Remove: function(id) {
        delete Rooms.Obj[id];
    },
    getIdByDbID: function(dbID) {
        var result = null;
        for(var room in Rooms.Obj) {
            var u = Rooms.Obj[room]; 
            if(u.dbID == dbID) var result = room;
        }
        if(result == null) return false;
        else return result;
    },
    getDbIDbyId: function(id) {
        return Rooms.Obj[id].dbID;
    }
}
Rooms.Listener();
module.exports = Rooms;

编辑:(如果有帮助的话)

当我在主文件上 console.log 五个套接字时

当我在rooms.js 文件上控制台记录五个套接字时

EDIT2:当我从fiveSocket 中删除var users = require('./users.js'); 时,当我在rooms.jsconsole.log 它工作时,为什么?
EDIT3:我还是有问题

如果您需要其他模块来源:
Users.JS: http://pastebin.com/Ynq9Qvi7
sockets.JS http://pastebin.com/wpmbKeAA

【问题讨论】:

  • 同理,路径是正确的,因为在同一个目录下(rooms.js和fiveSocket.js在同一个目录下)
  • 当我 console.log 登录 rooms.js 时,结果如下i.imgur.com/vnc6QU5.png
  • 当我 console.log 到主文件时,结果是 i.imgur.com/OuuuIRb.png
  • 当我从fiveSockets.js 中删除var users = require('./users.js'); 时,当我在rooms.js 中进行console.log 时它可以工作,为什么?
  • @christopherclark 当我评论了 Rooms.Listener();一切都像魔术一样,Rooms.Listener 有什么问题?

标签: javascript node.js


【解决方案1】:

“房间”需要“用户”,反之亦然,因此您正在尝试执行“循环依赖”。

快速搜索 node.js 需要循环依赖提供了很多东西,例如:

“模块中的循环依赖可能很棘手,并且难以调试 节点.js。如果模块 A 在完成设置之前需要('B') 它是导出,然后模块 B 需要('A'),它将返回一个 空对象,而不是 A 可能打算导出的对象。它使 逻辑意义上,如果 A 的导出没有设置,则在 B 中需要它 导致一个空的导出对象。尽管如此,这可能会很痛苦 调试,对于习惯使用这些的开发人员来说并不明显 循环依赖自动处理。幸运的是,有 解决问题的相当简单的方法。”

How to deal with cyclic dependencies in Node.js

【讨论】:

  • 感谢您的回答,但我不明白如何解决这个问题,我知道我需要重组代码,但是有没有简单的解决方案来解决这个问题?
  • 我认为最好的方法是尽可能多地删除依赖项。在完美世界中,您的“房间”和“用户”根本不应该有依赖关系(除了一些基本的混合),而是接收必要的数据作为参数。在 JavaScript 中,您不必包含“类”定义来访问类方法,只需提供对象并使用其数据即可。就像你在“Listener: function(users) {”中所做的一样
  • 问题解决了,感谢:)我已经通过了函数中的模块
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-07
  • 2018-11-20
相关资源
最近更新 更多