表单异步校验场景下如何从Promise获取返回值以阻止表单提交
Hey there! Let's work through this form validation issue you're facing. The core problem here is that your validateAddress function isn't returning the promise from your API call, so you can't access the error value in your form validation logic. Since you can't use async/await, we'll fix this with plain promise chaining.
First, Fix the validateAddress Function
Right now, your function doesn't return anything (so it defaults to undefined). We need to make it return the entire promise chain, so the error value becomes the resolved value of the promise:
function validateAddress(requestString) { // Return the promise from your API call so we can chain onto it later return callToTheAPIMethod(requestString).then((res) => { let error = ""; // Initialize with empty default const obj = res.getDataFromApi; // Your API response data const precision = /* Extract precision value from API response */; if (obj) { switch (precision) { case "exact": error = ""; break; case "number": case "near": case "range": case "street": error = "Address is incorrect. Please specify house number"; break; case "other": default: error = "Address is incorrect. Please provide more details"; } } else { // Handle case where API returns no valid data error = "Failed to validate address. Please try again"; } $(".address_error").text(error); return error; // This value will be passed to the next .then() }).catch((err) => { // Don't forget to handle API call failures! const errorMsg = "Address validation failed. Please check your input"; $(".address_error").text(errorMsg); return errorMsg; }); }
Adjust Form Validation Logic
Since validation is now asynchronous, you can't use a synchronous if check to block form submission. Instead, you'll need to:
- Prevent the default form submit behavior first
- Run your address validation (and other field checks)
- Only submit the form manually if all validations pass
Here's how to implement this:
// Attach to your form's submit event (replace #yourForm with your actual form selector) document.getElementById("yourForm").addEventListener("submit", function(e) { e.preventDefault(); // Stop the form from submitting immediately const requestString = /* Generate your address request string here */; // Run address validation first validateAddress(requestString).then((addressError) => { // Run your other form field validations here let otherFieldsValid = true; // Example: Check if a name field is filled if (!document.getElementById("name").value.trim()) { otherFieldsValid = false; $(".name_error").text("Name is required"); } // Add more checks for other fields as needed // If no errors, submit the form manually if (!addressError && otherFieldsValid) { this.submit(); } }); });
Why This Works
- By returning the promise from
validateAddress, you can use.then()to access the finalerrorvalue once the API call completes. - We prevent the default form submission upfront, then only trigger the actual submission if all validations (address + other fields) pass.
- We added a
.catch()block to handle API failures, which ensures your user gets feedback even if the API call goes wrong.
内容的提问来源于stack exchange,提问作者Gabriel Khabibulin

