从前端到后端数据库兔宝世界游戏程序神奇bug调试全过程,JavaScript中json运行原理初探

前几天开了一个休闲游戏项目的细分功能,大概就是模拟一个种地的系统,我实现的方案是使用前端typescript后端应用typescript+node.js+mongoDB实现业务逻辑

功能需求挺多,多人在线可以互相看见,作物有缺水和生病状态...还可以偷菜,大写了3天程序差不多1500行代码写成了,当然更多还是要归功于曾经写好的一些基本功能。

然后就出现了一个特别糟心的bug,种上地以后不显示成长进度条和文字,并且bug出现的时候也特别的诡异,有时出现,有时候又不会出现,特别奇怪,我就下断点调试这个bug。

先看看前端触发显示进度条和提示成长进度的ui程序出现了什么问题。

 ui直接返回enum采摘光了,然后就把所有的进度条和提示文字都隐藏了,继续看,作物刚刚种上,连成熟都没有怎么会定位状态在采摘光了,这不是很奇怪吗?,那我就继续回调查看状态的识别程序。

状态中表示首先验证的是yield,yield是一个可被玩家摘植物的列表 ,如果列表中没有果实了就返回采摘光了的状态。这一层回调明白了,因为yield这个列表没有东西了所以才返回状态为没有果实,但是这也很奇怪呀,种的时候yield列表就已经初始化好了。

那么就看一看加入作物到显示列表时候作物的构建程序是不是符合我的这个情况

 

这里返回的值就是空的,传过来新种下的作物就是空的了,那就只能在服务端的构建植物的程序处下断点调试,在服务端一看果然yield列表是空的。但是我检测json表中是有数据的,这是因为什么呢?百思不得其解,只能先判断什么情况下种下植物果实列表会是空的。

然后我就测试吧,重开服务端客户端并且在收获封包处理时下断,一顿调试直接调到了JavaScript底层这边基本上没有希望了,肯定这个路线是不对的。

 但这个地方的值确实会变动,再次重开发现了一个规律,只有在种下一个新的作物后收获新的作物的果实的时候才会触发清空json中reap列表中的内容所以我就直接按这个规律去调试程序,并且下断在收获点

点击收获,先判断是否在自己家种植是否在公共地皮种植的 

然后跳函数到完全自己获得该作物的所有果实函数,也就是自己种自己采收作物的函数 内,我发现在玩家获得物品后,有yield列表清理删除刚刚玩家采收后物品的删除函数跳进该函数

没有任何异样,但是果实列表清空的问题就在这20行里面了

我一点点的调下去,我万万没有想到的是竟然删除从总植物列表中获取的 作物数据中的果实列表中的内容被删除的时候会把json里面的数据也删除

这就更加奇怪了!!

删一个从数据库中载入内存的json列表中的数据竟然删到了另一个毫无关联的json里面

返回头看作物创建功能里面的初始化要存入的数据条创建过程,瞬间明白了

 这里传进去的是引用不是实际的数据,构建的整个系统所有后创建的json实际上都是内存引用,既然是内存引用那么系统在操作删除指定已采摘果实的函数删除的就是写入内存的那个通用json数据里面的内容,而非后面创建植物列表中的果实列表内容。

JavaScript,typescript里面内部的运行机制原来是这样的,那可真的省去了很多内存开销,那么我应该找一下json深浅拷贝的内容看一看

 

哇好复杂的拷贝过程呀,可能得专门创建一个拷贝函数用才能解决这个bug

那应该怎么去解决呢,我灵机一动

直接把json转换成字符串对象,然后放数据条的时候解析成json就可以了

 

 于是这个神奇的bug的修复成功了,调这个bug快调了6个小时。

 向后往前推的回顾一下:

1.引用式创建json对象的json作物条数据存入总条导致了总作物条数据集合和原本不应该改变的json条数据出现了对象引用式的关联

2.因为有关联所以删除作物果实数据列表的时候会删除这个不应该改变的json数据里面构建作物果实的数据改变

3.因为收获时删除改变,删除了果实所以导致创建新作物的时候果实列表为空

4.因为新创建果实列表为空所以即时创建的列表数据为空

5.因为返回过来列表为空所以前端初始化即时添加作物果实列表为空

6.因为果实列表为空所以ui检测作物状态时候为采摘光状态

7.因为是采摘光状态所以前端显示的是作物应该被铲除时的状态

8.因为只在新种下作物的时候会导致json和条数据引用所以只有新种的作物会触发bug而已经存库作物不会影响

9.这个bug就是这样,顺利解决bug

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值