当前位置: 首页 > Web前端 > JavaScript

Loading...done

时间:2023-03-27 00:13:29 JavaScript

简介在之前的界面开发过程中,为了提升用户在与后台交互时的体验,通常会展示Loading动画。Loading动画将在与后端的交互结束时关闭。这是一个很常见的需求,技术实现并不复杂。showLoading();axios.request(...).then(...).finally(()=>hideLoading());Node.js和大多数浏览器在2018年实现了Promise.prototype。finally()支持。Deno在2020年发布的1.0中也支持finally()。即使不支持,用await也很容易处理。showLoading()try{awaitaxios.request(...);}finally{hideLoading();}早些时候,jQuery通过jqXHR中的always()提供了支持。显示加载();$.ajax(...).done(...).always(()=>hideLoading());拦截器中的Loading...done逻辑接下来,为了所有接口调用的行为保持一致,同时为了在一处处理同一事物达到复用的目的,开始写Loading...done的逻辑在一些拦截器中。这对于单个远程接口调用是没有问题的。但是如果有这样一个业务逻辑呢:functionasyncdoSomething(){consttoken=awaitfetchToken();constauth=awaitremoteAuth(token);constresult=awaitfetchBusiness(auth);}假设上面的每次调用都使用了axios,axios在拦截器中注入了showLoading()和hideLoading()的逻辑。那么这段代码会依次弹出三个Loading动画。为一个业务播放多个Loading动画确实是一种糟糕的体验。CountLoading其实我们可以在showLoading()和hideLoading()中找到解决这个问题的方法。我们把这两个方法放到一个闭包环境中,然后用一个变量来记录调用次数:const{showLoading,hideLoading}=(()=>{letcount=0;functionshowLoading(){count++;if(count>1){return;}//TODO显示加载视图}functionhideLoading(){count--;if(count>1){return;}//TODO隐藏加载视图}})();包装业务逻辑而不是拦截个人不赞成用拦截器来处理接口。拦截器应该处理与请求本身强相关的事情,比如参数的预处理,响应的后处理等等。我不太同意在拦截器中处理界面上的东西。这种情况下,可以设计一个wrap函数来处理Loading的渲染,通过参数调用传入的业务逻辑。这个wrap函数可以这样写:asyncfunctionwrapLoading(fn){showLoading();尝试{返回等待fn();}最后{hideLoading();带参数awaitwrapLoading(fetchSomething);//单次远程调用,带参数awaitwrapLoading(()=>fetchSomething(arg1,arg2,arg3));//多次调用的组合逻辑constresult=awaitwrapLoading(()=>{consttoken=awaitfetchToken();constauth=awaitremoteAuth(token);returnawaitfetchBusiness(auth);});sinkwrapper函数降低了业务处理的复杂度。底层Ajax框架执行封装。远程调用业务时使用封装好的接口,避免直接使用Ajax库接口。比如对axios请求进行一层封装。异步函数请求(url,配置){config.url=url;returnawaitaxios.request(config);}如果需要显示Loading,可以扩展config,增加一个withLoading选项:asyncfunctionrequest(url,config){const{withLoading,...cfg}=config;cfg.url=网址;如果(!withLoading){返回等待axios.request(cfg);}尝试{showLoading();返回等待axios.request(cfg);}最后{hideLoading();}}如果扩展的业务参数比较多,可以考虑封装成一个对象,比如config.options,或者在封装的request中增加一个额外的参数:request(url,config,options),这些实现都不难,我不会详细介绍。有了这层封装,以后替换Ajax框架就相对容易了。只需要修改封装的请求函数即可,实现了业务层与框架/工具的解耦。