至少加载xx秒

产品说要优化一下这个loading

异步请求总有一些不确定性,比如手机网络差,服务器阻塞等,虽然大部分情况,我们的异步请求是响应非常迅速的,但是总有但是嘛。

在页面上、按钮上添加 loading 能够更好地向用户返回当前的加载状态,如果没有 loading 的反馈,用户看到白屏、卡住的界面是不友好的。

当我们添加了 loading 指示器以后,却发现大部分时间,接口都迅速相应了,这就导致 loading 一闪而过,甚至没有看清 loading 长什么样子。一个简单粗暴的办法:在异步请求的回调里面加一个 x 秒的 setTimeout,在 x 秒后隐藏 loading 指示器。这样的方法的确能够达到解决 loading 一闪而过的效果,但是无形之中给用户增加了 x 秒的等待时间。

请看 loading 指示器在不同持续时间的显示效果

不同持续时间的loading对比

点击打开微信小程序片段


Promise.all 文档

原理:

Promise.all(iterable) 方法返回一个 Promise 实例,此实例在 iterable 参数内所有的 promise 都“完成(resolved)”或参数中不包含 promise 时回调完成(resolve);如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败的原因是第一个失败 promise 的结果。
它通常在启动多个异步任务并发运行并为其结果创建 Promise 之后使用,以便人们可以等待所有任务完成。

因此我们只需要将我们的异步请求和一个定时器(设置 duration)封装成 Promise 并传入 Promise.all()中,然后 await 这个 Promise.all 回调完成即可,此时耗费的时间为:异步请求的时间 >= duration ? 异步请求的时间 : duration

当然,这个异步请求不一定是成功的,它可能由于用户提交的参数有误或者是服务端对用户的数据请求返回指定的错误,这时我们可以使用 Promise.all 的 reject 回调处理这些错误。

错误处理示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
async showGracefulToastWithError() {
wx.showLoading()
Promise.all([
new Promise(res => setTimeout(res, 50)),
new Promise((resolve, reject) =>
setTimeout(() => {
reject('出现错误啦')
}, 1000)
)
])
.then(() => {
wx.hideLoading()
})
.catch(err => {
// handle your error here
wx.hideLoading()
wx.showToast({
icon: 'none',
title: err
})
})
}

完结,撒花