天天看点

代码审查,异步调用的常见问题剖析

先来看一段代码,就是一小段而已:

这段代码乍一看,似乎没毛病。但是稍微思考一下,就能发现问题了。

首先,最直观的问题:缩进太深。缩进最深的地方是 24 个空格,也就是 6 层。一般我们认为 3 层以内的缩进比较容易阅读,超过 3 层应该考虑使用“extract method”方法进行重构。

接下来,看外层逻辑:

这是期望的执行顺序。

注意到 <code>wx.login</code> 是一个异步过程,所以实际上 <code>hideloading()</code> 并不会等登录过程结束就关闭了加载提示。所以第 2 个问题是忽略了异步执行的顺序。

马上可以想到使用 <code>wx.login()</code> 的 <code>complete</code> 参数来解决:

不过马上就引出了下一个问题:complete 还是太快!

为什么?我们再把内部的逻辑结构清理出来:

注意到 <code>wx.request</code> 仍然是一个异步过程,所以 <code>wx.login</code> 的 <code>success</code> 会立即结束,触发 <code>complete</code>。而这时候 <code>wx.request</code> 可能还在等待服务器响应。

那么是不是应该把 <code>wx.hideloading()</code> 放到内部逻辑中去?理论上来说,是的!

但实际情况是,内部逻辑分支较多,深次较深,既有同步逻辑,也有异步逻辑……考虑应该放在哪些地方,需要非常的谨慎。实际上,案例中的代码就已经在内部逻辑中放了一些 <code>wx.hideloading()</code>,只不过

覆盖不全;

因为最外层的 <code>hideloading()</code> 提前执行,失效了。

违反了规范性约束:成对逻辑应该尽量避免一对多的情况。

解释一下第 3 点,就是说:一个 <code>showloading()</code> 最好只对应一个 <code>hideloading()</code>。考虑到逻辑的复杂性,这不是强制约束规则,但应该尽量去避免。

处理的办法是,重构,将内部逻辑拆分出来;然后,将完成事件处理逻辑作为一个参数,一层层的往里传:

代码审查,异步调用的常见问题剖析

显然在当前的技术环境中,这并不是最优方案,还可以继续优化——反正都要封装,干脆封装成 promise。然后通过 <code>await</code> 调用转换成同步语法,处理起来会轻松得多。封装的具体过程在前两篇文章中有详细的讲解,这里就不赘述了。总之,我们封装了 <code>wx</code> 的异步版本 <code>awx</code>,在这里用就好:

喜欢此文,点个赞 ⇙

支持作者,赏个咖啡豆 ⇓

继续阅读