我在第 7 行的 console.log 打印正常。
主机.js
"use strict";
var engine = require('./engine.js');
var base = require('./base.js');
var player = new base.Avatar();
console.log(player.x);
class PillarGame extends engine.ServerGame {
connectPlayer(socket) {
var player = new base.Avatar();
this.add('players', player);
console.log("added player");
//announce
}
}
module.exports = {'HostedGame' : PillarGame};
但是在创建该对象并发出后,我的服务器发生了崩溃:
if (obj.hasOwnProperty(key) && _hasBinary(obj[key])) {
^
RangeError: Maximum call stack size exceeded
at Object.hasOwnProperty (native)
为什么会崩溃?
base.js 没有要求。
堆栈跟踪:
listening
connected
added player
/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:0
(function (exports, require, module, __filename, __dirname) { /*
RangeError: Maximum call stack size exceeded
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:24:22)
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:37:15)
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:47:40)
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:47:40)
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:47:40)
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:37:15)
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:47:40)
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:47:40)
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:47:40)
at _hasBinary (/Users/quantum/code/online/node_modules/socket.io/node_modules/has-binary-data/index.js:37:15)
server.js,崩溃
socket.emit("game.things", game.things);
var express = require('express');
var path = require('path');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var logic = require('./logic');
var hostedGame = require('./host');
var game = new hostedGame.HostedGame({'sockets' : io.sockets});
app.use(express.static(path.join(__dirname, 'public')));
server.listen(3000, function() {
console.log('listening');
});
io.on('connection', function(socket) {
console.log('connected'); //extrac
game.connectPlayer(socket);
//console.log("game.things['players']" + game.things['players']);;
socket.emit("game.things", game.things);
// socket.on('input', function(data) {
// game.input(socket, data);
// });
});
var loopAsync = function() {
setTimeout(loop, 10);
//setImmediate(loop);
}
var now = Date.now();
var last = now;
var dt = 0.00;
var rate = 10;
function loop() {
now = Date.now();
var delta = now - last;
last = now;
dt = dt + delta;
if (dt < rate) {
loopAsync();
return;
} else {
dt -= rate;
//if dt still > rate, repeat the following while true
var updates = game.loop();
//emit things
io.sockets.emit('player-positions', logic.players);
//io.to specific player
loopAsync();
}
}
loopAsync();
基础.js
"use strict";
class Component {
defaultMaxCharge() {
return [0];
}
constructor(options) {
options = options || {};
this.charge = [0];
if (options['maxCharge']) {
this.maxCharge = options['maxCharge'];
} else {
this.maxCharge = this.defaultMaxCharge();
}
}
loop() {
}
getValue(name, hash) {
return hash;
}
}
class Looper extends Component {
registrationNames() {
return ['loop'];
}
}
class Mover extends Looper {
loop() {
var velocity = this.thing.getValue('velocity');
var speed = this.thing.getValue('speed')['speed'];
var total = Math.abs(velocity.vx) + Math.abs(velocity.vy);
if (total <= 0) {
return;
}
var xx = velocity.mx / total * this.speedMod();
var yy = velocity.my / total * this.speedMod();
this.thing.x = this.thing.x + xx * speed;
this.thing.y = this.thing.y + yy * speed;
this.thing.x += velocity.vx;
this.thing.y += velocity.vy; //announce
}
}
//input components
class XWalker extends Component {
constructor(options) {
super(options);
this.vx = 0;
}
registrationNames() {
return ['input', 'velocity'];
}
getValue(name, hash) {
if (name == 'velocity') {
hash.vx = this.vx; //times speed
}
return hash;
}
processEvent(name, eventer, hash) {
if (name == 'input') {
if (hash.left) {
this.vx = -1;
} else if (hash.right) {
this.vx = 1;
} else {
this.vx = 0;
}
}
}
}
class YWalker extends Component {
constructor(options) {
super(options);
this.vx = 0;
}
registrationNames() {
return ['input', 'velocity'];
}
getValue(name, hash) {
if (name == 'velocity') {
hash.vy = this.vy; //times speed
}
return hash;
}
processEvent(name, eventer, hash) {
if (name == 'input') {
if (hash.up) {
this.vy = -1;
} else if (hash.down) {
this.vy = 1;
} else {
this.vy = 0;
}
}
}
}
class Thing {
spawnComponents(options) {
return [];
}
installComponents(options) {
this.componentRegistrations = {};
this.components = [];
var comps = this.spawnComponents(options);
for (var i = 0; i < comps.length; i++) {
var component = comps[i];
component.thing = this;
this.registerComponent(component);
this.components.push(component);
}
}
registerComponent(component) {
for (var i = 0; i < component.registrationNames().length; i++) {
var eventName = component.registrationNames()[i];
if (!this.componentRegistrations[eventName]) {
this.componentRegistrations[eventName] = [];
}
this.componentRegistrations[eventName].push(component);
}
}
getValue(name) {
var registered = this.componentRegistrations[name];
if (registered) {
var valueHash = {};
for (var i = 0; i < registered.length; i++) {
var component = registered[i];
valueHash = component.getValue(name, valueHash);
if (valueHash.stop) {
return valueHash;
}
}
return valueHash;
}
}
processEvent(name, eventer, hash) {
var registered = this.componentRegistrations[name];
if (registered) {
for (var i = 0; i < registered.length; i++) {
var component = registered[i];
component.processEvent(name, eventer, hash);
}
}
}
constructor(options) {
if (options && options['position']) {
this.x = options['position'].x * this.canvas.width;
this.y = options['position'].y * this.canvas.height;
} else {
this.x = 2.0;
this.y = 2.0;
}
this.installComponents(options);
this.active = true;
}
loop() {
for (var i = 0; i < this.components.length; i++) {
var component = this.components[i];
component.loop();
}
}
afterLoop() {
}
position() {
return {'x' : this.x, 'y' : this.y};
}
}
class Avatar extends Thing {
spawnComponents(options) {
return [new Mover(), new XWalker(), new YWalker()];
}
}
module.exports = {'Component' : Component, 'Thing' : Thing,
'Mover' : Mover, 'Looper' : Looper, 'XWalker' : XWalker, 'YWalker' : YWalker,
'Avatar' : Avatar};
最佳答案
server.js, crashes on socket.emit("game.things", game.things);
game.things 很可能是一个具有循环引用的复杂对象,socket.io 试图在发出之前将其转换为 JSON,但失败了。
关于javascript - 在模块内部实例化类时超出最大调用堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34278969/
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or
我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案
我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_
我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的