2021/09/15 开发问题解决记录
ericwxy

写在前面

昨天遇到了一个很奇怪的问题,解决的过程也给我带来了很多思考,在这里记录一下

问题描述

就在前天晚上临走前,测试反馈给我了一个问题,这个问题很奇怪只在测试的安卓机上才会出现。就是在 uni-app 开发的 mpaas 小程序中 tab 切换会导致 tab 下的列表数据错乱。

这个小程序的 tab 和列表的数据我是用 Flux 的数据流架构方式来处理的(所有的数据层级的操作都用 vuex 来管理)。三个 tab 下面的列表虽然 形式差不多但是数据来源不同,故我一开始采用的是三个相互独立的 数组去存放列表数据的。

这个小程序的 tab 和列表的数据我是用 Flux 的数据流架构方式来处理的(所有的数据层级的操作都用 vuex 来管理)。三个 tab 下面的列表虽然 形式差不多但是数据来源不同,故我一开始采用的是三个相互独立的 数组去存放列表数据的。

请求去重复的措施有以下几点,1:给 tab 切换和 filter 筛选条件切换的请求做了一个简单的防抖(短时间内会重复发请求的原因是 tab 切换会先重置 filter 筛选,故分别会触发这两个 条件变化的同一个不同参数的网络请求)。2:在 tab 切换的事件监听方法内取消 下拉刷新 和滚动加载的请求,并重置页码信息。3:全局的 loading 有点击遮罩,防止频繁点击造成的重复请求。4:在 vue 实例上封装了一个全局 loading 状态的变量,在请求方法的第一行判断如果该变量为 true 则直接短路 return 出请求方法。

解决过程

因为做过很多层的防止重复请求的措施,所以我第一时间就排除了重复网络请求造成错误的可能性。因为我在设计 vuex 的初期考虑到三个列表数据的相互独立,把三个列表存在了三个数组中,用三个不同的映射写在 getters 里来根据 tab 下标来判断返回哪一个数组给视图层。

我首先想:这些 vuex 中的数据是存在内存中的,我自己的手机和测试机比较明显的区别可能就在内存大小上,会不会原生分配给小程序的内存不足以处理三个独立的列表呢?于是我询问了测试那台测试的安卓机是不是内存不大得到了肯定的回答(测试机的内存是 4G,我的手机是 8G)。但是前端这点数据感觉不至于把 4 个 G 都撑爆吧… 哎,先记着到时候改成一个列表试试,反正 getter 那边用的映射 tab 切换也会清空数组,三个数组变一个数组是可行的。

于是说干就干咯,“三下五除二”我就合并了 state 和 mutations 中关于列表的操作。拿来测试机扫了一下真机调试然后马上我看到了效果,数据错乱的问题解决了一大部分,至少测试机的列表部分不会卡卡的了。

但是我发现,虽然说列表数据对了,但是 getters 里面的映射,不会随着 tab 下标的改变而改变,总是用第一个列表的映射。这谁遭得住… 于时我又开始新的尝试。

我心想,在 cardList 的 getter 里动态判断 用哪个映射行不通,我可不可在 视图层的 <template> 里面做条件渲染呢?(因为 页面上条件编译的部分没有出任何错)

于时 我将三个列表的 getter 从同一个,改成了三个独立的 getter 分别使用其对应的映射方法。然后在视图层这边 将 <CardList /> 组件 写成三个用 tab 下标来做条件渲染。结果效果也是很明显,我想应该是 Compiler 给 runtime 分担了部分的运算压力吧,把条件判断这一部分逻辑在编译的时候解决了七七八八,这样在运行时就不用 vuex 哪边去做条件判断了吧。

我拿着测试机 点来点去,发现还是有极小的概率会出现 tab 切换列表不清空的问题。我想起了之前遇到过的一个问题。就是在页面 走了 onHide() 生命周期之后在页面栈下层(非栈顶)的时候,改变页面上对应的数据状态,返回该页的时候响应的状态没有得到改变。会不会只要是视图部分不可见的时候改变它的状态就不起作用呢?

在代码里打了一个 debugger 调试后发现在每一次 tab 切换 <CardList /> 可见性改变之后 才会发 reload 的 action 。会不会是因为这个呀?于是我在 tab 切换方法的第一行写了 一个 清空列表的 commit 在列表可见性改变之前先用同步的方式清空列表。

刷新看结果。嗯,很有效。看来开发 uni-app 小程序 至少是开发 mpaas 的时候还是要在视图部分可见性变化之前完成数据的操作呀。

一些思考

通过这次这个问题我得出的以下两点思考。

  • 写代码一定要考虑扩展性,我把这叫 ETC(easy to change) 原则。像这次的这个问题,如果我没有用 Flux 架构,将数据于视图分层、函数之间职责分离,改起来会很崩溃的。毕竟是否定了最开始的数据结构设计的。所以 SOLID 原则里的单一职责原则 yyds 好嘛。
  • 移动端开发一定要多考虑设备的硬件限制和一些机型适配问题。毕竟移动端不是 pc。

继续加油吧。

 评论
评论插件加载失败
正在加载评论插件