当前位置: 首页 > news >正文

女装网站功能的建设恒丰建设集团有限公司 网站

女装网站功能的建设,恒丰建设集团有限公司 网站,池州网站建设有哪些公司,利川市网站建设前言 最近业务没有之前紧张了#xff0c;也是消失了一段时间#xff0c;也总结了一些之前业务上的问题。 和同事沟通也是发现普通的async await 封装api在复杂业务场景下针对于请求的业务逻辑比较多#xff0c;也是推荐我去学习一波ahooks#xff0c;由于问题起源于请求…前言 最近业务没有之前紧张了也是消失了一段时间也总结了一些之前业务上的问题。 和同事沟通也是发现普通的async await 封装api在复杂业务场景下针对于请求的业务逻辑比较多也是推荐我去学习一波ahooks由于问题起源于请求因此作者也是直接从 useRequest 开始看起。 附ahooks useRequest链接: https://ahooks-v2.js.org/zh-CN/hooks/async/ 实现 话不多说手写直接开始参考几个比较常用的 useRequest 能力来一个个实现吧。 基础版雏形 先上代码 useRequest.ts interface UseRequestOptionsProps {/** 请求参数*/initialData?: object;/** 请求成功回调*/onSuccess?: (res: any) void; }const useRequest (requestFn: (initialData?: object | string | [],) PromiseSetStateActionany,options: UseRequestOptionsProps, ) {const [data, setData] useStateSetStateActionany(null);const [loading, setLoading] useStateboolean(false);const [error, setError] useStatestring | null(null);const { initialData, onSuccess } options;useEffect(() {setLoading(true);setError(null);setData(null);request();}, [requestFn]);// useRequest业务逻辑const request async () {try {const res await requestFn(initialData);setData(res);// 请求成功响应回调onSuccess onSuccess(res);} catch (err) {err setError(JSON.stringify(err));} finally {setLoading(false);}};return { data, loading, error }; };export default useRequest;使用 const { data, loading, error } useRequest(queryCompensatoryOrderSituation,{initialData: {compensatoryId,}onSuccess: (res) {console.log(success request!, res);},}, );useRequest 对于请求函数的写法并无过多要求只要是一个异步function且返回一个promise对象即可传入useRequest的第一个参数中而第二个参数则是一系列的可选配置项雏形版本我们暂时只支持onSuccess。 手动触发 代码改造后 useRequest.ts interface UseRequestOptionsProps {/** 手动开启*/manual?: boolean;/** 请求参数*/initialData?: object;/** 请求成功回调*/onSuccess?: (res: any) void; }const useRequest (requestFn: (initialData?: object | string | [],) PromiseSetStateActionany,options: UseRequestOptionsProps, ) {const [data, setData] useStateSetStateActionany(null);const [loading, setLoading] useStateboolean(false);const [error, setError] useStatestring | null(null);const { manual, initialData, onSuccess } options;useEffect(() {setLoading(true);setError(null);setData(null);!manual request();}, [manual]);// useRequest业务逻辑const request async () {try {const res await requestFn(initialData);setData(res);// 请求成功响应回调onSuccess onSuccess(res);} catch (err) {err setError(JSON.stringify(err));} finally {setLoading(false);}};return { data, loading, error, request }; };export default useRequest;使用 const { data, loading, error, request } useRequest(queryCompensatoryOrderSituation,{manual: true,initialData: {compensatoryId,},onSuccess: (res) {console.log(success request!, res);},}, );request();手动执行的逻辑主要是根据manual参数砍掉useRequest mount阶段的渲染请求把执行请求的能力暴露出去在页面中去手动调用request()来触发。 轮询与手动取消 代码改造后 useRequest.ts interface UseRequestOptionsProps {/** 手动开启*/manual?: boolean;/** 请求参数*/initialData?: object;/** 轮询*/pollingInterval?: number | null;/** 请求成功回调*/onSuccess?: (res: any) void; }const useRequest (requestFn: (initialData?: object | string | [],) PromiseSetStateActionany,options: UseRequestOptionsProps, ) {const [data, setData] useStateSetStateActionany(null);const [loading, setLoading] useStateboolean(false);const [error, setError] useStatestring | null(null);const status useRefboolean(false);const pollingIntervalTimer useRefNodeJS.Timer | null(null);const { manual, initialData, pollingInterval, onSuccess } options;useEffect(() {setLoading(true);setError(null);setData(null);!manual request();}, [manual]);// useRequest业务逻辑const request async () {try {!status.current (status.current true);if (pollingInterval status.current) {pollingIntervalTimer.current setTimeout(() {status.current request();}, pollingInterval);}const res await requestFn(initialData);setData(res);// 请求成功响应回调onSuccess onSuccess(res);} catch (err) {err setError(JSON.stringify(err));} finally {setLoading(false);}};return { data, loading, error, request, cancel }; };// 取消 const cancel () {if (pollingIntervalTimer.current) {clearTimeout(pollingIntervalTimer.current);pollingIntervalTimer.current null;status.current (status.current false);} };export default useRequest;使用 const { data, loading, error, request, cancel } useRequest(queryCompensatoryOrderSituation,{manual: true,initialData: {compensatoryId,},pollingInterval: 1000,onSuccess: (res) {console.log(success request!, res);},}, );request();... // 轮询到理想数据后 cancel(); 轮询的支持在hook中主要用到了timer setTimeout的递归思路同时给出一个status状态值判断是否在轮询中当调用端执行cancel()status则为false当轮询开始则status为true。 而cancel()的能力主要也是取消了timer的递归请求逻辑并且轮询的业务场景和manual: true配合很多。 依赖请求串型请求 代码改造后 useRequest.ts interface UseRequestOptionsProps {/** 手动开启*/manual?: boolean;/** 请求参数*/initialData?: object;/** 轮询*/pollingInterval?: number | null;/** 准备用于依赖请求*/ready?: boolean;/** 请求成功回调*/onSuccess?: (res: any) void; }const useRequest (requestFn: (initialData?: object | string | [],) PromiseSetStateActionany,options: UseRequestOptionsProps, ) {const [data, setData] useStateSetStateActionany(null);const [loading, setLoading] useStateboolean(false);const [error, setError] useStatestring | null(null);const status useRefboolean(false);const pollingIntervalTimer useRefNodeJS.Timer | null(null);const {manual,initialData,pollingInterval,ready true,onSuccess,} options;useEffect(() {setLoading(true);setError(null);setData(null);!manual ready request();}, [manual, ready]);// useRequest业务逻辑const request async () {try {!status.current (status.current true);if (pollingInterval status.current) {pollingIntervalTimer.current setTimeout(() {status.current request();}, pollingInterval);}const res await requestFn(initialData);setData(res);// 请求成功响应回调onSuccess onSuccess(res);} catch (err) {err setError(JSON.stringify(err));} finally {setLoading(false);}};return { data, loading, error, request, cancel }; };// 取消 const cancel () {if (pollingIntervalTimer.current) {clearTimeout(pollingIntervalTimer.current);pollingIntervalTimer.current null;status.current (status.current false);} };export default useRequest;使用 const [mountLoading, setMountLoading] useStateboolean(false);useEffect(() {setMountLoading(true); }, [2000])const { data, loading, error, request, cancel } useRequest(queryCompensatoryOrderSituation,{initialData: {compensatoryId,},pollingInterval: 1000,ready: mountLoading,onSuccess: (res) {console.log(success request!, res);},}, );依赖请求的思路就是在hook中加入一个ready字段也是在基于manual一层的限制后又加了一层来判断是否在hook加载时是否做默认请求而当option中的ready更新为true时hook自动更新从而发起请求。 常用于页面中A请求完成后执行B请求B请求的ready字段依赖于A请求的data/loading字段。 防抖与节流 防抖和节流的实现比较简单依赖于lodash库包装了一下request函数的请求内容。 代码如下 useRequest.ts interface UseRequestOptionsProps {/** 手动开启*/manual?: boolean;/** 请求参数*/initialData?: object;/** 轮询*/pollingInterval?: number | null;/** 准备用于依赖请求*/ready?: boolean;/** 防抖*/debounceInterval?: number;/** 节流*/throttleInterval?: number;/** 请求成功回调*/onSuccess?: (res: any) void; }const useRequest (requestFn: (initialData?: object | string | [],) PromiseSetStateActionany,options: UseRequestOptionsProps, ) {const [data, setData] useStateSetStateActionany(null);const [loading, setLoading] useStateboolean(false);const [error, setError] useStatestring | null(null);const status useRefboolean(false);const pollingIntervalTimer useRefNodeJS.Timer | null(null);const {manual,initialData,pollingInterval,ready true,debounceInterval,throttleIntervalonSuccess,} options;useEffect(() {setLoading(true);setError(null);setData(null);!manual ready request();}, [manual, ready]);// 请求const request () {if (debounceInterval) {lodash.debounce(requestDoing, debounceInterval)();} else if (throttleInterval) {lodash.throttle(requestDoing, throttleInterval)();} else {requestDoing();} };// useRequest业务逻辑 const requestDoing async () {try {!status.current (status.current true);if (pollingInterval status.current) {pollingIntervalTimer.current setTimeout(() {status.current request();}, pollingInterval);}const res await requestFn(initialData);setData(res);// 请求成功响应回调onSuccess onSuccess(res);} catch (err) {err setError(JSON.stringify(err));} finally {setLoading(false);} };// 取消 const cancel () {if (pollingIntervalTimer.current) {clearTimeout(pollingIntervalTimer.current);pollingIntervalTimer.current null;status.current (status.current false);} };export default useRequest;使用 const { data, loading, error, request, cancel } useRequest(queryCompensatoryOrderSituation,{manual: true,initialData: {compensatoryId,},debounceInterval: 1000, // 防抖throttleInterval: 1000, // 节流onSuccess: (res) {console.log(success request!, res);},}, );for(let i 0; i 10000; i) {request(); }在hook中通过lodash.debounce/lodash.throttle来包装request函数主体通过option中的判断来执行对应的包装体函数。 缓存与依赖更新 改造后的代码最终代码如下 useRequest.ts import {useState,useEffect,useRef,SetStateAction,useCallback, } from react; import lodash from lodash;interface UseRequestOptionsProps {/** 手动开启*/manual?: boolean;/** 请求参数*/initialData?: object;/** 轮询*/pollingInterval?: number | null;/** 准备用于依赖请求*/ready?: boolean;/** 防抖*/debounceInterval?: number;/** 节流*/throttleInterval?: number;/** 延迟loading为true的时间*/loadingDelay?: number;/** 依赖*/refreshDeps?: any[];/** 请求成功回调*/onSuccess?: (res: any) void; }const useRequest (requestFn: (initialData?: object | string | [],) PromiseSetStateActionany,options: UseRequestOptionsProps, ) {const [data, setData] useStateSetStateActionany(null);const [loading, setLoading] useStateboolean(false);const [error, setError] useStatestring | null(null);const status useRefboolean(false);const pollingIntervalTimer useRefNodeJS.Timer | null(null);const {manual,initialData,pollingInterval,ready true,debounceInterval,throttleInterval,loadingDelay,refreshDeps,onSuccess,} options;useEffect(() {if (loadingDelay) {setTimeout(() {status setLoading(true);}, loadingDelay);}setError(null);setData(null);// 手动触发request!manual ready request();}, [manual, ready, ...(Array.isArray(refreshDeps) ? refreshDeps : [])]);// 请求const request () {if (debounceInterval) {lodash.debounce(requestDoing, debounceInterval)();} else if (throttleInterval) {lodash.throttle(requestDoing, throttleInterval)();} else {requestDoing();}};// useRequest业务逻辑const requestDoing async () {try {!status.current (status.current true);if (pollingInterval status.current) {pollingIntervalTimer.current setTimeout(() {status.current request();}, pollingInterval);}const res await requestFn(initialData);setData(res);// 请求成功响应回调onSuccess onSuccess(res);} catch (err) {err setError(JSON.stringify(err));} finally {setLoading(false);}};// 取消const cancel () {if (pollingIntervalTimer.current) {clearTimeout(pollingIntervalTimer.current);pollingIntervalTimer.current null;status.current (status.current false);}};// 缓存const cachedFetchData useCallback(() data, [data]);return { data, loading, error, request, cancel, cachedFetchData }; };export default useRequest; 使用 const [mountLoading, setMountLoading] useStateboolean(false); const [updateLoading, setUpdateLoading] useStateboolean(false);setTimeout(() {setMountLoading(true); }, 1000);setTimeout(() {setUpdateLoading(true); }, 2000);const { data, loading, error, request, cancel, cachedFetchData } useRequest(queryCompensatoryOrderSituation,{manual: true,initialData: {compensatoryId,},debounceInterval: 1000, // 防抖throttleInterval: 1000, // 节流refreshDeps: [mountLoading, updateLoading],onSuccess: (res) {console.log(success request!, res);},}, );缓存的主体思路是在useRequest中拿到第一次数据后通过useCallback来透出data依赖来保存同时向外暴露一个cachedFetchData来过渡data从null到请求到接口数据的过程。 依赖更新的思路则是在页面中给useRequest一系列依赖状态一并加入在hook的请求副作用中监听到页面中依赖改变则重新请求具体实现则是refreshDeps参数。 结尾 花了一上午时间一个简易版本的useRequest实现了也是通过实现学习到了一些请求思路在业务复杂的场景下也是很需要这类请求工具来让开发者的注意力从请求处理转移集中在业务逻辑中。
http://www.dnsts.com.cn/news/18962.html

相关文章:

  • 淘宝客可以自己做网站推广吗pc端网页视频怎么下载
  • django做待办事项网站电子商务营销的发展趋势
  • 网站建设费用会计入什么费用淘宝客做的好的几个网站
  • 王璞网站开发实战网站首页制作网站
  • 大型网站流量智能小程序开发
  • 坪山网站建设服务网络营销推广策划的步骤
  • 局域网网站开发软件密云富阳网站建设
  • 网站如何做优化好的外贸平台
  • 烟台专业做网站公司哪家好装修公司网站如何做网络推广
  • 电子商务网站制作公司卖产品的网站怎么做
  • php做网站示例白沟网站建设
  • 做街机棋牌上什么网站发广告页面在线设计网站
  • 做网站所需要的资质智能logo设计网站
  • 怎样查看网站关键词软件公司市值排名
  • 北京个人制作网站大数据工程技术
  • 免费营销网站制作模板北京中高风险地区最新名单最新
  • 用wordpress做企业网站汕头建设
  • 怎么做返利网站网页制作设计框架
  • wordpress图片站做环保网站案例分析
  • 郑州做网站优化最好的公司安徽网络推广
  • 应聘工作哪个网站比较好建站代理
  • 五个常见的电子商务网站网址cfensi.wordpress
  • 代刷网站推广河南快速网站备案
  • 做塑胶网站需要什么材料重庆网站建设注意事项
  • 怎么自己做网站发优惠券广东网站定制
  • 杨凌做网站中国最大的家装网站
  • 卖书的网站怎么做国内专门做旅游攻略的网站
  • 有没有专门做家纺的网站网站后台文章字体
  • 汕头网站建设科技有限公司在线支付的网站怎么做
  • 深圳网站建设公司地图南宁企业自助建站系统