多个表单验证,除了最后一个在 Vue 中停留在 Pending 状态

Multiple form validation except last one stuck at Pending state in Vue

我有一个 Ant Design 表单,针对多个输入进行了验证 <a-from-model>

<a-form-model
      ref="ruleForm"
      :model="form"
      :rules="rules"
      :label-col="labelCol"
      :wrapper-col="wrapperCol"
    >
<a-form-model-item has-feedback label="Git Clone Address(.git)" prop="git_address">
        <a-input v-model="form.git_address" />
      </a-form-model-item>
      <a-form-model-item has-feedback label="Number of Modules" prop="module_number">
      <a-form-model-item label="Notification Lists(seperated by ,)" prop="maillist">
        <a-input v-model="form.maillist" placeholder="johndoe@gmail.com" />
      </a-form-model-item>
      <a-form-model-item has-feedback label="CI/CD Stages" prop="stage">
        <a-checkbox-group v-model="form.stage">
          <a-checkbox value="1" name="stage"> Stage 1 </a-checkbox>
          <a-checkbox value="2" name="stage"> Stage 2 </a-checkbox>
          <a-checkbox value="3" name="stage"> Stage 3 </a-checkbox>
        </a-checkbox-group>
      </a-form-model-item>
      <a-form-model-item :wrapper-col="{ span: 14, offset: 4 }">
        <a-button type="primary" @click="onSubmit"> Create </a-button>
        <a-button style="margin-left: 10px" @click="onCancel"> Cancel </a-button>
      </a-form-model-item>
    </a-form-model>

现在要提交表单,我需要通过所有验证。这是 export default {data() { 的样子:

data() {
    let checkPending;
    let checkModuleNumber = (rule, value, callback) => {
      clearTimeout(checkPending);
      if (!value) {
        return callback(new Error('Please input the number'));
      }
      checkPending = setTimeout(() => {
        if (!Number.isInteger(value)) {
          callback(new Error('Please input digits'));
        } else {
          if (value < 1) {
            callback(new Error('Module number must at least be 1!'));
          } else {
            callback();
          }
        }
      }, 1000);
    };
    let checkGitAddress = (rule, value, callback) => {
      clearTimeout(checkPending);
      checkPending = setTimeout(() => {
        if (!value.endsWith(".git")) {
          callback(new Error("Please enter clone address that ends with .git!"));
        } else {
          callback();
        }
      }, 1000);
    };
    let checkModuleStage = (rule, value, callback) => {
      clearTimeout(checkPending);
      checkPending = setTimeout(() => {
        if (value.some((x) => x === "2") && value.some((x) => x === "3")) {
          callback(
            new Error(
              "You have selected both Stage 1 and Stage 2. Only one can be selected:"
            )
          );
        } else {
          callback();
        }
      }, 1000);
    };

这就是 rules 的样子:

rules: {
        git_address: [
          { required: true, message: "Please input git address", trigger: "change" },
          { validator: checkGitAddress, trigger: "change" },
        ],
        module_number: [
          { required: true, message: "Please input module number", trigger: "change" },
          { validator: checkModuleNumber, trigger: "change" },
        ],
        maillist: [
          { required: true, message: "Please input maillist", trigger: "change" },
        ],
        stage: [
          {
            type: 'array',
            required: true,
            message: 'Please select at least one stage',
            trigger: 'change',
          },
          { validator: checkModuleStage, trigger: "change" },
        ],
      },

methods里面我定义了下面两个函数:

onSubmit() {
      this.$refs.ruleForm.validate(valid => {
        if (valid) {
          this.display = true;
          alert('submit!');
        } else {
          console.log('error submit!!');
          return false;
        }
      });
    },
    onCancel() {
      this.$refs.ruleForm.resetFields();
    },

我现在遇到的问题是,每当我更改输入时,验证都非常快地完成。但是当我点击提交按钮时,除最后一个之外的所有检查都停留在checkPending状态,因此验证永远无法完成。有谁知道这是什么结果?非常感谢!

(我的猜测是因为所有的检查功能都是异步的但不确定是否是这种情况并且不知道如何解决它:(()

原来我需要做的就是删除所有checkpending函数,只保留错误处理。 async 函数在这种情况下不起作用。

clearTimeout(checkPending);
checkPending = setTimeout(() => {
    if ("some condition") {
          callback(
            new Error("some error")
          );
    } else {
          callback();
        }
}, 1000);