各位前端er们,这么久以来,大家觉得熟悉的界面request不合适吗???你可能会觉得这有什么不对,为什么不直接axios.get,fetch,请求发送,然后处理返回的数据,就完事了。真的那么简单吗?问题是,真的可以统一处理不同场景下的请求需求吗?让我们谈谈要求吧!下面说一下前端请求的场景。下面说一下前端请求的各种场景。下面是一些在发起请求时遇到的高频场景。什么时候发送请求,是一进入页面就触发,还是点击某个按钮后触发,还是某个数据改变后触发,还是……?你想在页面上显示请求状态吗?是否应该将某个请求封装成一个函数,使其可以重复调用,比如翻页请求;用户可能经常请求的接口是否应该用于数据缓存,比如几秒内会重复查看的数据?处理完一些数据后,需要对数据进行跨页面或跨模块的操作。怎么做更方便?不能全部放在全局状态;离线时能否安全提交数据?比如编辑器需要经常自动保存草稿,突然掉线怎么办?其他请求场景...这些请求场景需要在不同的项目或者同一个项目的不同位置进行不同的处理。如果我们简单地使用请求库来发起请求,将会失去性能和优雅。管理请求场景由于以上问题,出现了一个叫做请求场景管理(RSM,Requestscenemanagement)的概念。下面我们就来谈谈这个概念。先上图,英文图片,自己翻译。像Flux的概念,只是提出一套流程规范,然后开发者可以参考,改造,改造,形成自己独特的想法,然后编码实现。我的理解是,更像是在请求库上放上机械臂、油漆桶等,武装请求库,就像钢铁侠一样。这里,本规范提出了四个过程,分别是:请求时序描述了何时需要发送请求。初始化显示数据,比如刚进入某个界面或者子界面;人机交互触发CS交互,需要更改数据重新发送请求,如翻页、过滤、排序、模糊搜索等;预加载数据,比如在页面中预加载一页内容,预测用户点击某个按钮后会预取数据;操作服务器端数据,需要发出增删改查请求,如提交数据、删除数据等;同步服务器状态,比如在数据快速变化的场景下进行下一轮查询请求,操作某条数据后重新拉取数据;请求行为描述了如何处理请求。占位符请求、显示加载、骨架图或上次使用的真实数据;缓存高频响应,多次执行请求会使用新鲜数据;串行和并行的多个请求;频繁请求防抖,避免前端数据闪退,减轻服务器压力;重要的接口重试机制,降低网络不稳定导致请求失败的概率;静默提交,当只关心提交数据时,提交请求后直接响应成功事件,后台保证请求成功;离线提交,离线时提交数据会暂存在本地,联网后再提交联系;请求事件意味着发送带有请求参数的请求并获得响应。这是最常用的axios、fetch、XMLHttpRequest等,看!这里我们要重新认识一下以上请求方案的定位,它们只是请求场景管理的其中一个环节。响应数据管理,顾名思义就是统一管理响应数据,任何位置都可以对响应数据进行操作。这部分基本是配合react、vue等MVVM框架的状态机制使用,就好像有专门管理响应数据一样。通过redux和vuex,你可以在没有任何事件机制的情况下跨模块操作这些有状态的响应数据。移除缓存的响应数据,再次发起请求时会从服务器拉取;更新缓存的响应数据,可以在任意位置更新响应数据,对跨页面更新数据很有帮助;刷新响应数据,可以在任意位置刷新响应数据,对跨页面更新数据也很有好处;自定义设置缓存,在请求批量数据时,可以手动为批量数据逐条设置缓存,以满足后续单条数据的缓存命中;alova,一个RSM的实现库alova是我发现的一个比较好用的RSM实现库,因为它的设计真的很像axios,新手也能很快上手。同时,它也可以与任何请求库进行合作。在简单演示了alova的使用方法之后,我们终于要开始代码的实际运行了。在使用alova之前,我们需要先创建一个实例,假设我们在vue项目中使用它。import{createAlova}from'alova';importVueHookfrom'alova/vue';importGlobalFetchfrom'alova';constalovaInstance=createAlova({//请求接口前缀baseURL:'https://api.alovajs.org',//用于为mvvm库创建状态响应数据//vue项目传递给VueHook,react项目传递给ReactHookstatesHook:VueHook,//传递一个请求适配器,GlobalFetch是我们提供的fetchapi适配器//你想用axios也可以自定义一个适配器requestAdapter:GlobalFetch(),//是不是有点熟悉的味道beforeRequest(config){config.headers.token='tokenxxx';},asyncresponded(response){constjson=awaitresponse.json();if(json.code!==200){thrownewError(json.message);}returnjson.data;},});以Todo为例,发起一个todo详情请求//先定义一个request函数,这个函数返回一个request对象,表示一个请求的信息,但并不真正发送请求//它的用法很接近axiosconstgetTodoDetail=id=>alovaInstance.Get('/todo',{params:{id},//本地缓存50000毫秒,再次请求时会命中缓存,不会发起请求再次localCache:50000,});//发起请求const{//loading是加载状态值,加载时它的值为true,结束后会自动更新为false//在Vue3环境下,是一个Ref类型的值,可以通过loading.value访问,也可以直接绑定到接口loading,//statefulresponsedatadata:todoDetail,//请求错误对象,request有一个错误时的值,否则为undefinederror,//成功回调绑定onSuccess,//失败回调绑定onError,//完成回调绑定onComplete,}=useRequest(getTodoDetail(this.$params.todoId));//传入request对象发送请求onSuccess(todoListRaw=>{console.log('请求成功,你也可以在这里访问响应数据:',todoListRaw);});onError(error=>{console.log('请求失败,错误信息为:',error);});onComplete(()=>{console.log('请求完成,无论成功失败都会调用');});可以直接将useRequest返回的状态绑定设置到接口
