You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript封装Bootstrap校验函数时如何让forEach先执行完再返回

核心问题说明

执行顺序颠倒和forEach是否执行完成无关:
forEach遍历本身是同步执行的,但是你在遍历中给表单绑定的submit事件回调属于异步触发逻辑,只有当表单的提交事件被实际触发时才会执行,因此函数外层的打印逻辑会在绑定完所有事件监听器后立刻执行,早于提交事件触发后的回调逻辑。
同时你当前的bsvalidate函数仅完成了「给表单绑定提交校验规则」的操作,并没有当场执行校验,因此直接返回校验状态永远只能拿到初始值。

解决方案

根据使用场景不同有两种实现方式:

场景1:调用函数时当场校验所有表单,同步返回布尔结果

如果不需要等待提交事件触发,调用函数就直接完成所有表单校验、返回结果,可以直接遍历表单执行校验逻辑,不需要绑定提交事件监听器:

function bsvalidate() {
    'use strict'
    const forms = document.querySelectorAll('.needs-validation')
    let allValid = true
    Array.from(forms).forEach(form => {
        if (!form.checkValidity()) {
            allValid = false
        }
        form.classList.add('was-validated')
        console.log('inside forEach') // 1st console.log
        console.log('check>>', allValid)
    })
    console.log('outside forEach') // 2nd console.log
    return allValid
}

该方案为同步执行,你需要的打印顺序可以得到保证,调用函数后直接返回所有表单是否全部校验通过的布尔值。

场景2:表单提交触发校验时再返回结果

如果确实需要在表单提交时才触发校验、拿结果,可以用Promise封装逻辑,等待提交事件触发后再返回校验结果:

function bsvalidate() {
    'use strict'
    const forms = document.querySelectorAll('.needs-validation')
    // 返回Promise实例,提交事件触发后返回校验结果
    return new Promise(resolve => {
        let check = true
        Array.from(forms).forEach(form => {
            form.addEventListener('submit', function (event) {
                if (!form.checkValidity()) {
                    event.preventDefault()
                    event.stopPropagation()
                    check = false
                }
                form.classList.add('was-validated')
                console.log('inside forEach') // 1st console.log
                console.log('check>>', check)
                resolve(check)
            }, false)
        })
    })
}

// 调用方式1:then回调处理结果
bsvalidate().then(isValid => {
    console.log('outside forEach') // 2nd console.log
    // 后续业务逻辑写在这里
    console.log('校验结果:', isValid)
})

// 调用方式2:async/await语法(需要在async函数内使用)
// const isValid = await bsvalidate()
// console.log('outside forEach') // 2nd console.log
// console.log('校验结果:', isValid)

注意事项

  • 不要用全局变量window.check存储校验状态,容易被其他逻辑篡改,使用函数内部变量更安全。
  • 现在可以直接用Array.from把NodeList转为数组,不需要使用Array.prototype.slice.call的旧兼容写法。

内容的提问来源于stack exchange,提问作者damdafayton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 08:12:02