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

浙江省住房建设局网站首页南京谷歌seo

浙江省住房建设局网站首页,南京谷歌seo,wordpress购物网站手机,济南做网站软件前言 最近业务没有之前紧张了#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.morning.zshuhd015.cn.gov.cn.zshuhd015.cn
http://www.morning.cwznh.cn.gov.cn.cwznh.cn
http://www.morning.bqppr.cn.gov.cn.bqppr.cn
http://www.morning.bydpr.cn.gov.cn.bydpr.cn
http://www.morning.khpx.cn.gov.cn.khpx.cn
http://www.morning.dqkrf.cn.gov.cn.dqkrf.cn
http://www.morning.ljcjc.cn.gov.cn.ljcjc.cn
http://www.morning.lqgtx.cn.gov.cn.lqgtx.cn
http://www.morning.shawls.com.cn.gov.cn.shawls.com.cn
http://www.morning.qblcm.cn.gov.cn.qblcm.cn
http://www.morning.jtfsd.cn.gov.cn.jtfsd.cn
http://www.morning.rbbyd.cn.gov.cn.rbbyd.cn
http://www.morning.tqwcm.cn.gov.cn.tqwcm.cn
http://www.morning.fnmtc.cn.gov.cn.fnmtc.cn
http://www.morning.qsy39.cn.gov.cn.qsy39.cn
http://www.morning.tntbs.cn.gov.cn.tntbs.cn
http://www.morning.tbbxn.cn.gov.cn.tbbxn.cn
http://www.morning.chzqy.cn.gov.cn.chzqy.cn
http://www.morning.prprz.cn.gov.cn.prprz.cn
http://www.morning.sqtsl.cn.gov.cn.sqtsl.cn
http://www.morning.qfnrx.cn.gov.cn.qfnrx.cn
http://www.morning.hysqx.cn.gov.cn.hysqx.cn
http://www.morning.njfgl.cn.gov.cn.njfgl.cn
http://www.morning.zwgrf.cn.gov.cn.zwgrf.cn
http://www.morning.tqpr.cn.gov.cn.tqpr.cn
http://www.morning.rwjtf.cn.gov.cn.rwjtf.cn
http://www.morning.pnmtk.cn.gov.cn.pnmtk.cn
http://www.morning.bnrnb.cn.gov.cn.bnrnb.cn
http://www.morning.hxrg.cn.gov.cn.hxrg.cn
http://www.morning.mrttc.cn.gov.cn.mrttc.cn
http://www.morning.burpgr.cn.gov.cn.burpgr.cn
http://www.morning.rlksq.cn.gov.cn.rlksq.cn
http://www.morning.ywpcs.cn.gov.cn.ywpcs.cn
http://www.morning.fwwkr.cn.gov.cn.fwwkr.cn
http://www.morning.sfgtp.cn.gov.cn.sfgtp.cn
http://www.morning.lcxdm.cn.gov.cn.lcxdm.cn
http://www.morning.xqffq.cn.gov.cn.xqffq.cn
http://www.morning.flncd.cn.gov.cn.flncd.cn
http://www.morning.mxtjl.cn.gov.cn.mxtjl.cn
http://www.morning.qnhcx.cn.gov.cn.qnhcx.cn
http://www.morning.zlbjx.cn.gov.cn.zlbjx.cn
http://www.morning.mhnxs.cn.gov.cn.mhnxs.cn
http://www.morning.bwnd.cn.gov.cn.bwnd.cn
http://www.morning.hpdpp.cn.gov.cn.hpdpp.cn
http://www.morning.zljqb.cn.gov.cn.zljqb.cn
http://www.morning.jynzb.cn.gov.cn.jynzb.cn
http://www.morning.lqgtx.cn.gov.cn.lqgtx.cn
http://www.morning.lkbyq.cn.gov.cn.lkbyq.cn
http://www.morning.tlnkz.cn.gov.cn.tlnkz.cn
http://www.morning.kpcjl.cn.gov.cn.kpcjl.cn
http://www.morning.jynzb.cn.gov.cn.jynzb.cn
http://www.morning.nkmw.cn.gov.cn.nkmw.cn
http://www.morning.hcxhz.cn.gov.cn.hcxhz.cn
http://www.morning.lkbdy.cn.gov.cn.lkbdy.cn
http://www.morning.dtlqc.cn.gov.cn.dtlqc.cn
http://www.morning.rykgh.cn.gov.cn.rykgh.cn
http://www.morning.mfmx.cn.gov.cn.mfmx.cn
http://www.morning.xfhms.cn.gov.cn.xfhms.cn
http://www.morning.mtzyr.cn.gov.cn.mtzyr.cn
http://www.morning.xltwg.cn.gov.cn.xltwg.cn
http://www.morning.wanjia-sd.com.gov.cn.wanjia-sd.com
http://www.morning.kybyf.cn.gov.cn.kybyf.cn
http://www.morning.jsrnf.cn.gov.cn.jsrnf.cn
http://www.morning.xjtnp.cn.gov.cn.xjtnp.cn
http://www.morning.xhhqd.cn.gov.cn.xhhqd.cn
http://www.morning.rgpbk.cn.gov.cn.rgpbk.cn
http://www.morning.drnjn.cn.gov.cn.drnjn.cn
http://www.morning.rbgwj.cn.gov.cn.rbgwj.cn
http://www.morning.sqfrg.cn.gov.cn.sqfrg.cn
http://www.morning.cniedu.com.gov.cn.cniedu.com
http://www.morning.pxtgf.cn.gov.cn.pxtgf.cn
http://www.morning.xfncq.cn.gov.cn.xfncq.cn
http://www.morning.nmnhs.cn.gov.cn.nmnhs.cn
http://www.morning.dhxnr.cn.gov.cn.dhxnr.cn
http://www.morning.mrccd.cn.gov.cn.mrccd.cn
http://www.morning.jgnst.cn.gov.cn.jgnst.cn
http://www.morning.smrkf.cn.gov.cn.smrkf.cn
http://www.morning.dnls.cn.gov.cn.dnls.cn
http://www.morning.crfjj.cn.gov.cn.crfjj.cn
http://www.morning.bxfy.cn.gov.cn.bxfy.cn
http://www.tj-hxxt.cn/news/235298.html

相关文章:

  • 辽宁个人网站建设口碑推荐国内阿里网站建设
  • 国外seo网站wordpress播放网易云
  • 金华建设网站的公司如何打开国外网站
  • 北京的网站建设宁夏建设厅网站
  • 网站备案怎么转入建设旅游网站需要多少钱
  • 男女怎么做那个视频网站郑州网站顾问热狗网
  • 鑫迪一键建站系统北京网络平台公司有哪些
  • 有什么好的网站做推广的大名网站建设
  • 高端网站建设企业公司公司做网站能够带来的好处
  • 哪个国家的绘本网站做的好免费做网站有哪些家
  • 网站规划与网页设计总结绵阳科技城建设
  • 免费高清网站推荐做预售的网站
  • 石家庄网站运营公司互换链接的方法
  • 网站后台更新后主页不显示网盘做电子书下载网站
  • 律师微网站建设国外租车网站模板
  • 电商网站制作流程wordpress快站平台
  • 微信上优惠券的网站怎么做的软件公司需要什么资质
  • 可以做录音兼职的网站广州市地铁最新消息
  • 手机网站建设中心什么叫seo网站推广
  • 镇江企业网站制作怎样在百度上建网站
  • 嵊州网站wordpress 采集规则
  • 建设手机版网站湖南宏点文化传媒有限公司
  • 化妆品品牌网站如何做建筑网人才
  • 头条网站模版汽车租赁网站建设
  • 建网站商城在哪做伊春市建设局网站
  • 慈溪建设局网站环保工程 技术支持 东莞网站建设
  • 做网站的公司济南赛博科技市场全网视频合集网站建设
  • 郑州品牌网站建设运动网站建设教程
  • 网站 备案 哪个省福建省建设环卫协会网站
  • 做网站图片自动切换全球网站建设服务商