NodeJS某些模块无法正常工作

5
我正在使用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 fiveSocket时 输入图像描述

当我在rooms.js文件中使用console.log fiveSocket时 输入图像描述

编辑2:当我从fiveSocket中删除var users = require('./users.js');,当我在rooms.js中使用console.log它可以工作,为什么?
编辑3:我仍然有问题

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


1
当我在rooms.js中使用console.log时,这是结果http://i.imgur.com/vnc6QU5.png - user5672329
1
当我在主文件中使用console.log时,这是结果http://i.imgur.com/OuuuIRb.png - user5672329
1
当我从fiveSockets.js中移除了var users = require('./users.js');后,当我在rooms.js中使用console.log时它是起作用的,为什么? - user5672329
1
@christopherclark 当我注释掉了 Rooms.Listener() 这一行,一切都像魔术般地正常工作了,Rooms.Listener 有什么问题吗? - user5672329
1
@gnerkus http://pastebin.com/Ynq9Qvi7 - user5672329
显示剩余8条评论
1个回答

0

"Rooms"需要"Users",反之亦然,因此您试图执行“循环依赖”。

在node.js中搜索要求循环依赖会得到很多结果,例如:

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

或者如何处理Node.js中的循环依赖


谢谢您的回答,但我不明白如何解决这个问题。我知道我需要重构代码,但是否有任何简单的解决方案? - user5672329
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - zamuka
问题已解决,谢谢 :) 我已经通过了函数中的模块。 - user5672329

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接