让我们先看一段代码。这只是一小段:
导出函数loginWithWx() {
wx . show loading({ title : ' log in . '});
wx.login({
成功: res={
wx.request({
URL : ` $ { ApiRout } wx/$ { RES . code } `,
方法 ' get ',
成功: res={
const { data }=res。
const jwt=app . GlobalDATa . jwt=data?jwt
if (jwt) {
wx.reLaunch({ url: ')./index/index ' });
wx . HideLoadIng();
}
否则{
ShowMessage(data.message || '登录时出错 ');
wx . HideLoadIng();
}
},
fail: res={
显示消息( '请求超时,请稍后再试 ');
}
});
wx . HideLoadIng();
},
fail: res={
console . log(RES);
}
});
wx . HideLoadIng();
}
乍一看,这个代码似乎没问题。但是如果你稍微考虑一下,你就会发现问题所在。
首先,最直观的问题:缩进太深。最深的压痕是24个空间,或6层。一般来说,我们认为3层内的压痕更容易阅读,超过3层,我们应该考虑使用“提取方法”来重建。
接下来,看看外部逻辑:
wx.showLoading()
wx.login()
wx.hideLoading()
这是所需的执行顺序。
请注意,wx.login是一个异步进程,因此hideLoading()实际上不会在登录进程结束时关闭加载提示。所以第 2 个问题是忽略了异步执行的顺序。
您可以立即想到使用wx.login()的完整参数来解决这个问题:
wx . ShowLoAding();
wx.login({
complete: ()=wx.hideLoading()
});
然而,下一个问题马上出现了:complete 还是太快!
为什么?我们将清理内部逻辑结构:
wx.login({
成功: ()={
wx.request({
success: ()={ },
fail: ()={ }
})
},
fail: ()={ }
})
请注意,wx.request仍然是一个异步过程,因此wx.login的成功将立即结束,触发完成。Wx.request可能仍在等待服务器响应。
那么wx.hideLoading()应该放入内部逻辑吗?理论上,是的!
然而,实际情况是有许多内部逻辑分支和更深层次的逻辑分支。同步逻辑和异步逻辑都有……需要非常谨慎地考虑把它们放在哪里。事实上,本例中的代码已经在内部逻辑中放入了一些wx.hideLoading(),但是
覆盖面不完整;
因为隐藏加载()的最外层是预先执行的,所以它失败了。
违反规范约束:成对逻辑应该尽量避免一对多的情况。
解释第三点,也就是说,显示加载()最好只对应于隐藏加载()。考虑到逻辑的复杂性,这不是一个强制性的约束规则,但应该尽可能避免。
解决办法是重构和分解内部逻辑。然后,将完整的事件处理逻辑作为一个参数,并逐层传递:
显然,在当前的技术环境下,这不是最佳解决方案,可以进一步优化。——无论如何都应该打包,并打包为承诺。然后通过等待调用将其转换为同步语法,这更容易处理。封装的具体过程已经在前两篇文章中详细解释过了,这里不再重复。简而言之,我们已经封装了wx awx的异步版本,在这里使用很好:
导出异步函数AsyncLogginWithWx(){
wx . show loading({ title : ' log in . '});
尝试{
返回wait internal process();
捕捉(错误)
显示消息( '请求超时,请稍后再试 ');
}终于{
wx . ShowLoAding();
}
//用局部函数封装内部逻辑。
//主要是做尝试.捕捉.看起来更清楚
异步函数internalProcess() {
const { code }=wait awx . log in();
const { data }=awx.request({
URL : ` $ { ApiRout } wx/$ { code } `,
方法 ' get ',
});
const jwt=app . GlobalDATa . jwt=data?jwt
if (jwt) {
wx.reLaunch({ url: ')./index/index ' });
}其他{
ShowMessage(data.message || '登录时出错 ');
}
}
}
像这篇文章,订单赞
支持作者,赏个咖啡豆
发表评论