时间:2018年11月06日
这两天有这样的一个需求:在下载按钮上加一个下载中的loading动画。如今的状况是用户点击下载按钮时没有一点反馈,觉得没点上,会点击好几回,以后一下就下载好几回。
这种问题是人之常情,因此解决它无可厚非,但是解决的时候遇到了一些比较麻烦的问题。
下载函数在点击执行按钮执行函数调用的别的文件的方法,就像下面这样:promise
// a文件
// 点击按钮执行的函数
const main = () => {
downloadFile()
}
// b文件
// 具体下载函数
const downloadFile = () => {
// 下载部分代码
}
复制代码
若是仅仅是这样还好,我能够在main
函数中加上修改是否展现加载动画的变量,比方说下面这样:bash
// a文件
// 点击按钮执行的函数
const main = () => {
loading = true;
downloadFile();
loading = false;
}
复制代码
但是这个downloadFile
函数是个异步函数,因此若是想上面这样写的话loading
变量只会瞬间变一下,不会在downloadFile
函数执行完成以后再变成false
。
一开始我是打算用promise
来把main
函数包裹起来,在then
里面把loading
改为false
。事实证实这种方法确实可行,只是须要把reslove
传递过去,比方说这样:异步
// a文件
// 点击按钮执行的方法
return new Promise((reslove) => {
const main = () => {
loading = true;
downloadFile(reslove);
loading = false;
}
})
// b文件
const downloadFile = (reslove) => {
// 下载部分代码
reslove();
}
复制代码
后来思考以后发现这样的作法其实有点多余,彻底能够不用Promise
的。咱们须要新建一个修改loading
值的函数。函数
setLoadingStatus = (err, status) => {
if (err) {
message.error(err.message || err);
return this.exportTableLoading = false;
}
this.exportTableLoading = status;
}
复制代码
调用方法也比较简单:动画
// 有错
setLoadingStatus(err, false);
// 没错
setLoadingStatus(null, true);
复制代码
以后咱们把这个方法做为参数传递给downloadFile
函数,在downloadFile
函数中调用方法便可。ui
// b文件
const downloadFile = (setLoadingStatus) => {
// 下载部分代码
if (err) {
setLoadingStatus(err, false);
}
setLoadingStatus(null, true);
}
复制代码
这里咱们不用担忧说setLoadingStatus
函数被调用两次,由于若是有错,在执行setLoadingStatus
函数错误状况时,就会直接return
错误内容,就算下面有接收到setLoadingStatus
函数的正确状况也不会执行。
因此总体下来就是这样的:this
// a文件
// 定义修改loading的函数
setLoadingStatus = (err, status) => {
if (err) {
message.error(err.message || err);
return this.exportTableLoading = false;
}
this.exportTableLoading = status;
}
// 点击按钮执行的函数
const main = () => {
loading = true;
downloadFile(setLoadingStatus);
}
// b文件
const downloadFile = (setLoadingStatus) => {
// 下载部分代码
if (err) {
setLoadingStatus(err, false);
}
setLoadingStatus(null, true);
}
复制代码
不一样文件之间也能够互相调用函数,不用考虑传递过去以后就没法修改loading
值的问题,由于其自己调用的仍是a
文件中的setLoadingStatus
函数。spa