如何在表单提交前等待异步调用执行完成?
如何在表单提交前等待所有异步Blur请求完成
我明白你的痛点——表单提交时,那些在输入框失去焦点时触发的异步更新请求可能还没跑完,导致数据没同步就提交了。下面是一套可行的解决方案,核心思路是跟踪所有待完成的异步请求,确保它们全部结束后再让表单提交:
步骤说明
- 用一个数组来记录所有还在pending状态的异步请求Promise
- 在每个
blur事件触发时,把fetch请求的Promise加入数组,请求完成(无论成功失败)后再从数组中移除 - 监听表单的
submit事件,先阻止默认提交行为,等所有pending的请求都完成后再手动提交表单
修改后的代码实现
首先,添加一个变量来跟踪pending请求:
// 存储所有待完成的异步更新请求 let pendingUpdateRequests = [];
然后更新你的blur事件处理逻辑:
/** * 更新网站 */ $('.website').on('blur', function () { const websiteId = this.id; const website = this.value; // 创建fetch请求的Promise const updatePromise = fetch(`/api/edit?id=${websiteId}&url=${website}`) // 注意:这里修正了URL参数格式,用标准的?key=value&key2=value2,后端才能正确解析 .then(() => { console.log(`网站 ${websiteId} 更新完成`); }) .catch(err => { console.error(`网站 ${websiteId} 更新失败:`, err); }) .finally(() => { // 无论成功失败,都从pending数组中移除该请求 pendingUpdateRequests = pendingUpdateRequests.filter(p => p !== updatePromise); }); // 将请求加入pending数组 pendingUpdateRequests.push(updatePromise); });
最后添加表单提交的拦截处理:
$('form').on('submit', async function (e) { // 先阻止表单默认提交行为 e.preventDefault(); const currentForm = this; // 可以在这里添加加载提示,比如显示"正在保存数据..." // $('.loading').show(); try { // 等待所有pending的更新请求都完成 await Promise.all(pendingUpdateRequests); // 所有请求完成后,手动提交表单 currentForm.submit(); } catch (error) { console.error('部分更新请求失败:', error); // 这里可以根据业务需求选择: // 1. 提示用户后继续提交表单 // alert('部分数据保存失败,是否继续提交?'); // currentForm.submit(); // 2. 终止提交,让用户修正问题 // alert('数据保存失败,请重试'); } finally { // 隐藏加载提示 // $('.loading').hide(); } });
关键注意事项
- URL参数格式:你原来的URL
/api/edit/${websiteId}&${website}不符合HTTP参数规范,后端大概率无法正确解析,所以改成了/api/edit?id=${websiteId}&url=${website},记得根据你的后端接口调整参数名 - 错误处理:一定要在
finally(或者catch+then)里移除pending数组中的Promise,否则数组会不断积累失效的请求,导致后续提交逻辑出错 - 用户体验:建议在等待过程中添加加载提示,让用户知道系统在处理中,避免重复提交
内容的提问来源于stack exchange,提问作者Alex Ironside
相关产品推荐
相关产品推荐

