表单提交校验失败时promise.then未执行,主因是校验函数未返回promise或未调用resolve/reject;应统一返回promise、用allsettled汇总结果、防重复提交、正确处理fetch及错误提示时机。

表单提交时校验失败,Promise.then没执行
常见原因是校验函数没返回 Promise 实例,或内部 resolve/reject 没被调用。比如写了 new Promise((resolve, reject) => { if (valid) resolve(); }) 却漏掉 else reject(),导致 Promise 永远 pending。
实操建议:
- 所有校验函数必须显式返回
Promise,哪怕同步校验也要包一层Promise.resolve()或Promise.reject() - 避免在
then里直接修改 DOM;先统一收集错误,再批量渲染,否则多个异步校验并发时 DOM 更新会打架 - 使用
event.preventDefault()阻止默认提交,且只在所有校验通过后才手动触发form.submit()
多个字段并行校验,但需要等全部完成再汇总结果
用 Promise.all() 最直接,但它只要一个失败就整体 reject,而表单校验通常需要知道哪些字段错、哪些对。这时候该用 Promise.allSettled()。
实操建议:
-
Promise.allSettled([checkEmail(), checkPassword(), checkUsername()])返回每个 Promise 的{status: 'fulfilled'|'rejected', value|reason}对象数组 - 注意兼容性:
Promise.allSettled在 Node.js 12.9+ 和现代浏览器支持,IE 完全不支持,需用 polyfill 或降级为Promise.all().catch()+ 手动兜底 - 别把耗时操作(如密码强度实时检测)也塞进并行队列——用户还没输完就发请求,既浪费又易出错
校验函数里调用 fetch API,但报错 “Failed to execute 'fetch' on 'Window': Illegal invocation”
这通常发生在你把 fetch 赋值给变量再调用,比如 const req = fetch; req('/api/check')。此时 this 绑定丢失,fetch 内部找不到所属环境上下文。
实操建议:
- 始终以
fetch(...)形式调用,不要解构或赋值后调用 - 网络校验必须加超时控制,否则用户可能卡在 loading 状态:用
AbortController包裹fetch,并在 Promise 外层套Promis.race([fetch(...), timeoutPromise]) - 服务端返回非 2xx 状态码时,
fetch不会自动 reject,需手动检查response.ok并调用reject()
用户快速连续点击提交按钮,导致重复请求和状态混乱
本质是 Promise 没做防抖或锁机制,每次点击都新建一套异步流程,DOM 状态和请求互相覆盖。
实操建议:
- 提交按钮点击后立即置为
disabled,并在 Promise settled 后恢复(无论成功失败),避免视觉与逻辑脱节 - 用一个布尔变量
isSubmitting做简单锁:点击时检查为true就直接 return - 更稳妥的做法是把整个校验逻辑封装成可取消的 Promise 工厂函数,配合
AbortSignal中断前一次未完成的请求
最常被忽略的是错误提示的清除时机——不是在点击时清空,也不是在每个校验函数里单独清,而应在所有校验开始前统一重置提示区,否则旧错误残留会误导用户。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











