我的代码中的承诺仅在首次执行时解决,这是带有reCAPTCHA验证的简单表单提交。通过调试,我知道浏览器解释器会到达await captchaVerification()
行并在那里停止。第一次执行可以正常工作。
contactForm.addEventListener('submit', async (e) => {
e.preventDefault();
await captchaVerification()
const data = new FormData(contactForm)
_alert.innerHTML = 'Sending message...'
_alert.setAttribute('class', `alert show`);
ajax(contactForm.method, contactForm.action, data)
.then(([r, t]) => outcome(r ? r = 'success' : r = 'error', t))
.catch(e => outcome('error', e))
});
Hastebin的完整上下文:https://hastebin.com/oyuvoyeluv.js
从您发布的链接中可以看到,在您的captchaVerification
函数中,您检查了验证码是否曾经被渲染过,如果没有,则渲染并验证resolve
或reject
。问题是如果resolve
为真,则您永远不会reject
或isRendered
。
function captchaVerification() {
return new Promise((resolve, reject) => {
captcha.style.display = 'block';
const verifyCallback = (response) => {
if (response) {
captcha.style.display = 'none'
grecaptcha.reset()
return resolve(response)
} else {
grecaptcha.reset()
return reject('Invalid captcha verification.')
}
}
// The problem is here as you do nothing if the captcha was
// previously rendered.
if (!isRendered) {
grecaptcha.render('g-recaptcha', {
'sitekey': 'my-secret-key',
'theme': 'dark',
'callback': verifyCallback
})
isRendered = true;
}
})
}
它完全取决于captchaVerification
实现。如果函数返回相同的承诺。下次不会解决。就像Singelton
。因此最好始终创建new promise
。
const promise = new Promise(r => setTimeout(r, 100, Math.random()))
const captchaVerification = () => promise;
const captchaVerificationRe = () => new Promise(r => setTimeout(r, 100, Math.random()));
async function main() {
let res = await captchaVerification();
console.log(res); // 0.3251446189302283
res = await captchaVerification("sffsfs");
console.log(res); // 0.3251446189302283
res = await captchaVerificationRe();
console.log(res); // 0.06299211055753262
res = await captchaVerification("sffsfs");
console.log(res); // 0.721527810718094
}
main();