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

这段Promise.all表单验证代码为何报TypeError?如何修复?

问题描述

我有一个包含多个表单的页面,每个表单对应独立的JavaScript文件,其中的验证方法如下:

function validateForm(){
        return new Promise((resolve, reject) => {
            fetch(urls.validate)
                .then((r) => r.json())
                .then((json) => {
                    if (json.Success){
                        resolve("Complete!");
                    }else{
                        resolve(json.ErrorHtml);
                    }
                });
        });
    }

页面加载时,我尝试把不同的验证方法存入数组,最初写法是:

var validationScripts = [];
validationScripts.push("eisForm.validateForm();");
validationScripts.push("background.validateForm();");

当用户进入最后一个表单点击按钮时,需要执行所有验证脚本,我写了如下异步函数:

async function runValidation(){
    const results = await Promise.all(validationScripts.map(script => script()));
    console.log(results);
}

此时出现TypeError: script is not a function错误。我怀疑是方法后带了(),于是改成存储方法引用,但还是报相同错误。我需要实现所有Promise等待完成,并获取所有resolved值的集合。

更新后的示例代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title></title>
</head>
<body>
<script>
    var test = test || {};

    test.eisForm = (() => {
        async function validateForm(){
            await fetch('https://jsonplaceholder.typicode.com/todos/1')
              .then((response) => response.json())
              .then((json) => {return json;});
        }

        return {
            validateForm: validateForm
        }
    })();

    test.background = (() => {
        async function validateForm(){
            await fetch('https://jsonplaceholder.typicode.com/todos/1')
              .then((response) => response.json())
              .then((json) => {return json;});
        }

        return {
            validateForm: validateForm
        }
    })();


    var validationScripts = [];
    validationScripts.push(test.eisForm.validateForm);
    validationScripts.push(test.background.validateForm);

    async function runValidation(){
        const results = await Promise.all(validationScripts.map(script => script()));
        console.log(results);
    }

    window.onload = function(){
        runValidation();
    }

</script>
</body>
</html>
问题原因与修复方案

1. 初始写法的核心问题

最初你把字符串"eisForm.validateForm();"存入数组,执行script()时是在调用字符串,而字符串不是函数类型,必然触发TypeError。

2. 方法引用写法的隐藏问题

改成存储方法引用后仍有问题,看更新的示例代码,关键错误是**validateForm函数没有返回有效结果**:

async function validateForm(){
    // 仅await了fetch流程,但没有返回最终数据
    await fetch('https://jsonplaceholder.typicode.com/todos/1')
      .then((response) => response.json())
      .then((json) => {return json;});
}

虽然async函数默认返回Promise,但内部await后未返回值,导致这个Promise最终resolve的是undefined;同时混用await和.then()的写法冗余,也容易引发逻辑疏漏。

3. 正确修复步骤

步骤1:修正validateForm的返回逻辑

简化写法并确保返回处理后的数据:

// test.eisForm为例,test.background同理修改
test.eisForm = (() => {
    async function validateForm(){
        const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
        const json = await response.json();
        return json; // 返回最终数据,async自动包装为Promise
    }

    return {
        validateForm: validateForm
    }
})();

步骤2:保持数组存储函数引用的正确写法

你更新代码里的这部分是对的,继续保留:

var validationScripts = [];
validationScripts.push(test.eisForm.validateForm);
validationScripts.push(test.background.validateForm);

步骤3:runValidation函数逻辑无需修改

现有写法可以正常实现需求:Promise.all会等待所有验证Promise完成,最终返回所有resolved值组成的数组:

async function runValidation(){
    const results = await Promise.all(validationScripts.map(script => script()));
    console.log(results); // 输出两个待办事项对象组成的数组
}

4. 额外注意事项

  • 如果原始业务中fetch可能出现请求失败,建议在validateForm中添加try/catch捕获错误,避免单个验证失败导致整个Promise.all被reject;
  • 永远不要在数组中存储字符串形式的函数调用,直接存储函数引用才是正确的方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 07:32:02