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

使用try-finally结构执行状态重置

原代码

const commitForm = async () => {btnLoading.value = true;isCommitted.value = true;//过滤出显示字段的列表let showFieldsList = [];for (let comp of compList.value) {if (comp.isShow) {showFieldsList.push(comp);}}//必填校验for (let comp of showFieldsList) {if (comp.isRequired && comp.isShow) {if (comp.type === "showPic") {if (comp.picUrl) {formData.value[comp.prop] = comp.picUrl;}} else if (comp.type === "subForm") {const subForm = comp.subForm;if (subForm) {// 子表单必填字段列表let propList = [];for (let subComp of subForm) {if (subComp.isConfigRequired) {propList.push({prop: subComp.prop,label: subComp.label,});}}const subFormFillDataStr = formData.value[comp.prop];const subFormFillDataArr = JSON.parse(subFormFillDataStr ?? "[]");if (subFormFillDataArr.length === 0 && propList.length > 0) {message.error(`请填写子表单数据`);return;}for (let item of propList) {for (let subFormFillData of subFormFillDataArr) {if ((subFormFillData[item.prop] ?? "") === "") {message.warning(`${item.label}是必填字段`);return;}}}}} else if (comp.type === "checkBox") {if (formData.value[comp.prop] == "others" ||(Array.isArray(formData.value[comp.prop]) &&formData.value[comp.prop].length === 0) ||(formData.value[comp.prop] ?? "") === "") {message.warning(`${comp.label}是必填字段`);return;}if (formData.value[comp.prop].includes("others") &&!formData.value[comp.prop].some((item) => item.startsWith("others-"))) {message.warning(`${comp.label}字段的其他选项勾选但未填写`);return;}} else if ((formData.value[comp.prop] ?? "") === "") {message.warning(`${comp.label}是必填字段`);return;}//校验手机号if (comp.isValidateTel) {if (!/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(comp.sensitiveInfoTxt)) {message.warning(`${comp.label}格式错误`);return;}}// 正则表达式校验if (comp.regExp && comp.regExp !== "") {const res = validateCompValue(comp);if (!res) {return;}}//相等校验if (comp.sameValueAsCompValue) {if (formData.value[comp.prop] !==formData.value[comp.sameValueAsCompValue]) {message.warning(`${comp.label}字段配置的两次输入内容不同`);return;}}}}const copyFormState = JSON.parse(JSON.stringify(formData.value));for (let comp of compList.value) {if (["checkBox", "dataBind"].includes(comp.type)) {if (Array.isArray(copyFormState[comp.prop])) {copyFormState[comp.prop] = copyFormState[comp.prop].join(",");copyFormState[comp.prop] = rearrangeOthers(copyFormState[comp.prop]);}}if (comp.type === "dateTime") {if (copyFormState[comp.prop]) {copyFormState[comp.prop] = dayjs(copyFormState[comp.prop]).format("YYYY-MM-DD HH:mm");}}}const res = await validateTryUpdateOrder(props.workConfCode,props.formWebUuid);if (res === "covered") {return;}const params = {workConfCode: props.workConfCode,parentOrderId: route.query.orderId,subFormWebUuid: props.formWebUuid,};SmartFormApi.subFormNewRecord(params, copyFormState).then(async (result) => {if (result.data.code === 200) {message.success("已提交表单");emit("updateFormStatus", "已完成");} else {message.error(result.data.message);btnLoading.value = false;isCommitted.value = false;}}).catch((err) => {console.error(err);btnLoading.value = false;isCommitted.value = false;});
};

需要一进入这个函数就给按钮置灰,防止重复提交,但是函数内部return很多。

如果给每个return前都加上恢复按钮正常功能,则会造成大量的工作量和代码冗余,且不利于后续扩展。

可以使用try-finally结构,将代码改为

const commitForm = async () => {btnLoading.value = true;isCommitted.value = true;try {//过滤出显示字段的列表let showFieldsList = [];for (let comp of compList.value) {if (comp.isShow) {showFieldsList.push(comp);}}//必填校验for (let comp of showFieldsList) {if (comp.isRequired && comp.isShow) {if (comp.type === "showPic") {if (comp.picUrl) {formData.value[comp.prop] = comp.picUrl;}} else if (comp.type === "subForm") {const subForm = comp.subForm;if (subForm) {// 子表单必填字段列表let propList = [];for (let subComp of subForm) {if (subComp.isConfigRequired) {propList.push({prop: subComp.prop,label: subComp.label,});}}const subFormFillDataStr = formData.value[comp.prop];const subFormFillDataArr = JSON.parse(subFormFillDataStr ?? "[]");if (subFormFillDataArr.length === 0 && propList.length > 0) {message.error(`请填写子表单数据`);return; // 校验失败,退出执行
            }for (let item of propList) {for (let subFormFillData of subFormFillDataArr) {if ((subFormFillData[item.prop] ?? "") === "") {message.warning(`${item.label}是必填字段`);return; // 校验失败,退出执行
                }}}}} else if (comp.type === "checkBox") {if (formData.value[comp.prop] == "others" ||(Array.isArray(formData.value[comp.prop]) &&formData.value[comp.prop].length === 0) ||(formData.value[comp.prop] ?? "") === "") {message.warning(`${comp.label}是必填字段`);return; // 校验失败,退出执行
          }if (formData.value[comp.prop].includes("others") &&!formData.value[comp.prop].some((item) => item.startsWith("others-"))) {message.warning(`${comp.label}字段的其他选项勾选但未填写`);return; // 校验失败,退出执行
          }} else if ((formData.value[comp.prop] ?? "") === "") {message.warning(`${comp.label}是必填字段`);return; // 校验失败,退出执行
        }//校验手机号if (comp.isValidateTel) {if (!/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(comp.sensitiveInfoTxt)) {message.warning(`${comp.label}格式错误`);return; // 校验失败,退出执行
          }}// 正则表达式校验if (comp.regExp && comp.regExp !== "") {const res = validateCompValue(comp);if (!res) {return; // 校验失败,退出执行
          }}//相等校验if (comp.sameValueAsCompValue) {if (formData.value[comp.prop] !==formData.value[comp.sameValueAsCompValue]) {message.warning(`${comp.label}字段配置的两次输入内容不同`);return; // 校验失败,退出执行
          }}}}const copyFormState = JSON.parse(JSON.stringify(formData.value));for (let comp of compList.value) {if (["checkBox", "dataBind"].includes(comp.type)) {if (Array.isArray(copyFormState[comp.prop])) {copyFormState[comp.prop] = copyFormState[comp.prop].join(",");copyFormState[comp.prop] = rearrangeOthers(copyFormState[comp.prop]);}}if (comp.type === "dateTime") {if (copyFormState[comp.prop]) {copyFormState[comp.prop] = dayjs(copyFormState[comp.prop]).format("YYYY-MM-DD HH:mm");}}}const res = await validateTryUpdateOrder(props.workConfCode,props.formWebUuid);if (res === "covered") {return; // 校验失败,退出执行
    }const params = {workConfCode: props.workConfCode,parentOrderId: route.query.orderId,subFormWebUuid: props.formWebUuid,};await SmartFormApi.subFormNewRecord(params, copyFormState).then((result) => {if (result.data.code === 200) {message.success("已提交表单");emit("updateFormStatus", "已完成");} else {message.error(result.data.message);// 接口返回错误,需要重置状态throw new Error(result.data.message);}});} catch (err) {console.error(err);} finally {// 无论成功失败,最终都重置状态btnLoading.value = false;isCommitted.value = false;}
};

主要优化点说明:

1. 使用 try-finally 结构,确保在任何情况下(包括所有 return 点)都会执行状态重置

2. 将所有校验失败的情况通过 return 退出,最终都会走到 finally 块

3. 接口调用失败时通过 throw new Error 触发 catch 块,最终也会走到 finally 块

4. 成功提交后仍然会执行 finally 块重置状态,这符合业务逻辑

这样修改后,不需要在每个 return 前都写状态重置的代码,既减少了重复代码,也避免了遗漏重置状态的情况。
 
http://www.hskmm.com/?act=detail&tid=13837

相关文章:

  • java03预习
  • x6831卡顿分析
  • 实测对比:权威榜单之微信排版软件Top5(含详细测评)
  • 【F#学习】布尔运算优先级
  • 粘连字符验证码的分割与识别思路
  • 深入解析:【Spark+Hive+hadoop】基于spark+hadoop基于大数据的人口普查收入数据分析与可视化系统
  • part 8
  • 【本地音乐库】的搭建管理工具推荐
  • 扭曲变形验证码的图像处理与识别思路
  • 每日收获
  • C++中std::map容器中元素删除方法汇总 - 详解
  • 物理半程与半时问题
  • 从用户态到内核态:Windows CC 技术深度解析(第一篇:DNS隧道)
  • 9.22 科研小结:不要总是预设成功,失败才是常态
  • STM32光强传感器实验详解 - 实践
  • 在CodeBolcks下wxSmith的C++编程教程——从Hello world开始讲述wxSmith使用基础
  • 【Azure Batch】使用Start Task来挂载Storage Blob
  • HP notebook set your key to action key /multimedia key
  • newDay01
  • springboot 整合Redis实现发布/订阅功能
  • CCPC online 2025题解 ( A~H+K)
  • 2025.9.22总结 - A
  • 实用指南:GESP三级考纲+三级考试知识点详解
  • github操作备忘录
  • 9.22每日总结
  • 算法人生
  • 动态规划专题
  • 【51单片机】【protues仿真】基于51单片机PM2.5温湿度测量蓝牙架构
  • 每日反思(2025.9.22)
  • 洛谷题单指南-进阶数论-P4942 小凯的数字