我正在为我的API使用express.js开发移动应用程序的后端。对于此移动应用程序,用户使用手机号码登录,将OTP代码发送到他们的手机,并且他们需要将收到的OTP发送回服务器以进行验证。当用户首次尝试登录时,他们将其手机号码发布到服务器,然后进行大量处理,然后通过SMS网关向他们发送OTP。现在,当此请求仍在进行时,我需要等待用户通过POST请求将OTP发送到另一条路由,对其进行验证,然后在第一个正在进行的POST请求中继续执行适当的步骤。经过网上搜索后,我最终决定将verifyOTP路由的app.post方法包装到一个函数中,该函数创建并返回一个新的Promise,然后对其进行解析或在验证后拒绝它。重新启动服务器后,这是我第一次执行此操作,效果非常好,仅此而已。它仅在第一次工作,然后在随后的连续时间内,没有解决或拒绝应创建的新承诺,并且对登录路径的第一个请求仍在等待。我尝试了很多类似的事情,例如使该函数使verifyOTP路由异步包装,并在路由内部创建promise,而不是将其包装在一个路由中,但仍然没有用。你能帮助我吗?为了找到该问题的解决方案,我简化了过程,并使用以下代码对实际情况进行了模拟,它很好地模拟了问题:这是模拟第一个请求:app.get("/test", async function(req, res) { console.log("Test route\n"); var otpCode = Math.floor(Math.random() * (9999 - 2)) + 1; var timestamp = Date.now(); otp = { code: otpCode, generated: timestamp }; console.log("OTP code sent: " + otpCode + "\n"); console.log("OTP sent.\n"); res.end(); /* verifyOTP().then(function() { console.log("Resolved OTP verification\n\n"); res.end(); }).catch(function() { console.log("Bad\n\n"); res.end(); });*/});这是verifyOTP路由:var otp;app.post("/verifyOTP", function(req, res) { console.log("POST request - verify OTP request\n"); var msg; if ((Date.now() - otp.generated) / 1000 > 30) { msg = "OTP code is no longer valid."; res.status(403).json({ error: msg }); } else { var submitted = req.body.otp; if (submitted !== otp.code) { msg = "OTP code is incorrect."; res.status(403).json({ error: msg }); } else { msg = "Verified."; res.end(); } } console.log(res.statusCode + " - " + res.statusMessage + "\n"); console.log(msg + "\n");});只需提一下,这并不是我服务器中唯一需要OTP验证的地方,尽管验证后发生的事情的实现方式有所不同。因此,如果解决方案仍然可以使代码可重复用于多个实例,我将不胜感激。
1 回答

缥缈止盈
TA贡献2041条经验 获得超4个赞
好吧,在我自己进行了一些进一步的研究之后,我放弃了对此用例使用Promises的方式,而是使用RxJS的Observables。
尽管我必须进行一些细微的修改,但它几乎可以按照我想要的方式解决了我的问题。
对于那些偶然发现我的问题并为我面临的同样问题寻求解决方案的人:
承诺只能被解决或拒绝一次,据我所知,除非Promises函数完成运行,否则您无法使用相同的代码创建一个新的(如果我对此代码有误,请更正我,我真的很感激,这只是基于我个人的观察和猜测),除非您创建了一个全新的Promise,否则您将无法再次解决它。
在这种情况下,我们将根据侦听器(或js中所谓的内容)做出Promise,因此,除非删除侦听器,否则答应中扭曲的函数将无法完成运行(我认为),并且您不会创建一个新的Promise。
另一方面,Observables可以根据需要进行多次重用,有关此内容可在Promises和Observables之间进行比较,请参见此内容,这是一个很好的教程,可以帮助您了解Observables以及如何使用它们。见这对如何安装RxJS节点。
但是,请注意-由于某种原因,一旦您订阅了一个observable,传递给observable.subscribe()的函数中使用的变量将保持不变,它不会随着您对观察者路由的每个新请求而更新。因此,除非找到一种方法将可更改的变量传递到可观察的定义内的observer.next()函数中,否则您将得到错误的结果。
添加回答
举报
0/150
提交
取消