es6+react+mobx之Reaction doesn't converge to a stable state after 100 iterations
来源:互联网 发布:mysql front 5.3 注册 编辑:程序博客网 时间:2024/06/16 19:52
前言
近期项目开发技术开始转向react。对于react中的state管理,目前主要使用redux或mobx来进行管理。在作出比较后,选择mobx来进行state的管理微笑。
开展
使用es6+react+mobx,实现需求,疯狂的编写代码奋斗。一个巨大的坑悄悄的在等着踩大哭。
高潮
咦,换个浏览器来跑跑,看看效果如何。满心期待中羡慕。一开始就是使用chrome开发调试,chrome就不用管了。next --》firefox。firefox很给力,一切正常,没毛病。那再来下一个Safari。页面打开,what!!!怎么一直在装圈圈惊讶。说是迟那时快,打开浏览器控制台。一把红色的小叉叉提示出问题了难过。仔细一看控制台输出如下error:Reaction doesn’t converge to a stable state after 100 iterations。。。啥,遍历了一百次,这是什么鬼。其他浏览器都是正常的呀。而且es6转es5也考虑了兼容性,使用了es5-shim。
定位过程
既然出现了,那就得消灭它。一步步得开始漫长的定位过程。是不是非法操作state。于是对有操作state的地方进行详细排查,删除复杂逻辑代码,删除到最后就剩下一个框框了可怜。但是问题依然存在,啊~~~要疯啦骂人。好吧,这肯定不是我的代码写的有问题,我确定,因为哥的代码都快删除光了可怜。既然业务代码没啥问题,那就对引入的模块源码开始质疑了。是不是源码有问题。开启调试模式,重点盯在抛异常的这段源代码上。附上这段源码:
function runReactionsHelper() { globalState.isRunningReactions = true; var allReactions = globalState.pendingReactions; var iterations = 0; while (allReactions.length > 0) { if (++iterations === MAX_REACTION_ITERATIONS) { resetGlobalState(); throw new Error(("Reaction doesn't converge to a stable state after " + MAX_REACTION_ITERATIONS + " iterations.") + (" Probably there is a cycle in the reactive function: " + allReactions[0])); } var remainingReactions = allReactions.splice(0);var remainingReactions = allReactions.splice(0);for (var i = 0, l = remainingReactions.length; i < l; i++) remainingReactions[i].runReaction(); } globalState.isRunningReactions = false;}
当调试到var remainingReactions = allReactions.splice(0);执行完这行代码后,remainingReactions是空的,length为0再见。不对呀,remainingReactions的值应该是allReactions的所有值。但为什么是空的。那就进入splice方法中看看。这会让人感到奇怪疑问。splice方法是浏览器自带方法,怎么进的去。没错,是进不去,但是浏览器的版本稍微低一点。那就有可能了。我的Safari就是稍微低了那么一点(8.1),才出现此文中提到的问题。版本9以上没这个问题。这就是模块es5-shim干的活了。好那我们进去看看,一探究竟奋斗。进去后发现问题了。附上相应的源码:
splice: function splice(start, deleteCount) { var O = ES.ToObject(this); var A = []; var len = ES.ToUint32(O.length); var relativeStart = ES.ToInteger(start); var actualStart = relativeStart < 0 ? max((len + relativeStart), 0) : min(relativeStart, len); var actualDeleteCount = min(max(ES.ToInteger(deleteCount), 0), len - actualStart); var k = 0; var from; while (k < actualDeleteCount) { from = $String(actualStart + k); if (owns(O, from)) { A[k] = O[from]; } k += 1; }...}
咦,这行代码var actualDeleteCount = min(max(ES.ToInteger(deleteCount), 0), len - actualStart);有问题呀,为什么是取最小值min。当deleteCount这个参数不传时,那么actualDeleteCount得到的结果只能是0,也就意味着不会删除。且返回值是空。怎么会这样了???带着这个问题开启谷歌之旅,最终找到了答案。es5和es6这两者对splice方法的定义标准有差异、、、。哦买噶等。es5中第二个参数deleteCount不传的话,默认值是0,而es6中默认值是全部。好吧,我服了再见。
结局
这好像并不是源码的锅,那是谁的锅。只能把锅甩给定标准的人了。锅是甩了。但Safari浏览器问题还没解决呀。其实这问题的根源已经定位出来了,那解决方法自然就能找到了得意。解决办法很简单,那就是修改源码,修改谁的源码?那当然是mobx的源码,因为是它使用了splice方法呀。而且第二个参数没添加,那么我们就给加上去大笑。修改文中引入的第一段mobx源代码,修改前:
var remainingReactions = allReactions.splice(0);
修改后:
var remainingReactions = allReactions.splice(0,allReactions.length);
重新编译打包,打开Safari浏览器,圈圈转一下消失了,数据正常加载渲染。大功告成,欧耶。
- es6+react+mobx之Reaction doesn't converge to a stable state after 100 iterations
- matlab kmeans :failed to converge in 100 iterations
- Field "state" doesn't have a default value
- 翻译君Mobx,Ten minute introduction to MobX and React
- MySQL之Field 'email' doesn't have a default value
- Pushing a Geneic List of <T> to View state
- error: address doesn't contain a section that points to a section in a object file
- React Native 之 State
- React Native -- mobx
- React+mobx入门教程
- React Mobx使用基础
- error:'a' doesn't name a type
- AFNetworking: AFHTTPRequestOperation doesn't work after stand by mode
- How to involve a new JAR which doesn't exist in MVN Repository
- Field Doesn't Have a Default Value
- 【java】:selection doesn't contain a maintype
- C++ doesn't name a type
- React之 Props与State
- B+树
- 湖北民族学院oj 1780 (BFS) 之 马的移动
- iOS swift实现图片不重复保存至相册
- 数据库管理系统DBMS概论
- 初入级接口写法及思路
- es6+react+mobx之Reaction doesn't converge to a stable state after 100 iterations
- SSM杰信商务平台项目day07
- C++子类型关系
- Best Time to Buy and Sell Stock II
- C++抽象编程——递归策略(3)——生成排列数(2)
- 【IMWeb训练营作业】组件化开发
- NS3实例分析second.cc_Building a Bus Network Topology
- CocoaAsyncSocket + Protobuf 处理粘包和拆包问题
- Linux用户必看:29个必须掌握的常用