如何让Firebase中的Invisible reCAPTCHA调用表现得像Promise并等待回调
让Firebase隐形reCAPTCHA的回调触发后再继续执行代码
你的问题核心在于:当前renderRecaptcha函数里,await new RecaptchaVerifier只是等待实例创建完成,但reCAPTCHA的callback是异步触发的,所以await renderRecaptcha()之后,isRecaptchaRendered大概率还是false,没法直接执行后续任务。
要让reCAPTCHA的调用表现得像Promise,只需要把renderRecaptcha改造成返回一个Promise,让这个Promise在callback触发时再resolve即可,这样await就能精准等待到回调执行的时机。
修改后的完整代码如下:
// 不再需要全局的isRecaptchaRendered标志 const renderRecaptcha = () => { return new Promise((resolve, reject) => { recaptchaVerifier.current = new firebase.auth.RecaptchaVerifier( "recaptcha-container", { size: "invisible", callback: () => { resolve(); // 回调触发时,让Promise完成 }, "expired-callback": function() { console.log("reCAPTCHA expired"); // 可选:过期时可以reject Promise,方便捕获错误 reject(new Error("reCAPTCHA已过期")); }, } ); }); }; // 注意:onSubmit必须声明为async函数才能用await async function onSubmit() { console.log("before rendering"); try { // 这里会暂停执行,直到reCAPTCHA的callback被调用 await renderRecaptcha(); console.log("after rendering (回调已触发)"); // 直接在这里执行后续任务即可,因为已经确保回调完成了 // 执行后续任务 } catch (error) { console.error("reCAPTCHA处理失败:", error); } }
关键说明:
- 用Promise包裹RecaptchaVerifier的实例化逻辑,把
callback的触发作为Promise的resolve时机,这样await就能等待到你需要的节点。 - 原有的全局标志
isRecaptchaRendered可以直接去掉,因为await完成就代表回调已经执行了。 - 给
expired-callback加上reject逻辑,能在验证码过期时捕获错误,避免代码卡住。
内容的提问来源于stack exchange,提问作者prafful patil
相关产品推荐
相关产品推荐

