我是nodejs的新手。我正在测试一个承诺,但有一个问题。 这是我的问题。
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.get('/', async function(req,res){
console.log(222);
res.send("Hello!!!");
let check;
try {
console.log(3333);
check = await test();
console.log(4444);
} catch (err) {
console.log("Error : ", err);
}
console.log(111, check);
});
function test () {
return new Promise (resolve => {
console.log(5555);
app.get('/test', function(req, res) {
count = count + 1;
res.send(count.toString());
resolve("hahahaha");
})
})
}
app.listen(9000, function(){
console.log("hehehehe");
});
在get'http://localhost:9000'回调中,我等待'http://localhost:9000/test'的结果来做点事情。问题是,它第一次运行正常。但是从第二个开始,promise.resolve()函数不起作用。 这是我的第一次日志:
hehehehe
222
3333
5555
4444
111 'hahahaha'
这是我的第二次日志:
222
3333
5555
promise.resovle()
不起作用。它一直在等待,我听不懂。
编辑:这是在@Aritra Chakraborty先生的帮助下修改后,使用EventEmitter进行注册和smsVerifyCode的解决方案
var express = require('express');
var userControler = require('../Controler/user');
var router = express.Router();
var utils = require('../Helper/Utils');
var user_model = require('../Models/user');
const TIMEOUT_VERIFY = 300000;
const CODE_EXPIRED = 0;
const CODE_VALID = 1;
const CODE_INVALID = 2;
const CONTACT_EXISTED = 3;
const DATABASE_ABUSED = 4;
const events = require('events');
const emitter = new events.EventEmitter();
function timeout_verify_sms_emitter (time) {
setTimeout(() => {
emitter.emit('timeout_sms');
}, time);
}
function verify_code(codeGen) {
return new Promise((resolve, reject)=>{
emitter.on("verifySMS", (data)=>{
if (data === codeGen) {
resolve(CODE_VALID);
}
else {
resolve(CODE_INVALID);
}
})
emitter.on('timeout_sms', () =>{
resolve(CODE_EXPIRED);
});
})
}
router.get('/',function(req,res){
res.send("Welcome to the Earth!!!");
})
router.post('/signup', async function(req,res){
let verifyCode;
let checkContact;
let codeGen = utils.generateCode();
try {
checkContact = await user_model.checkContact(userData.contact);
if (checkContact === true) {
res.send(CONTACT_EXISTED);
}
else {
//call send sms to contact function here
//exam : sendSMS(contact)
//
timeout_verify_sms_emitter(TIMEOUT_VERIFY);
verifyCode = await verify_code(codeGen);
}
}
catch (err) {
console.log("Error : ", err);
}
if (verifyCode === CODE_EXPIRED) {
res.send(CODE_EXPIRED);
}
else if (verifyCode === CODE_VALID) {
var result = userControler.processUserData(req.body);
if (result) {
res.send(CODE_VALID);
}
else {
res.send(DATABASE_ABUSED);
}
}
else {
res.send (CODE_INVALID);
}
})
router.post('/signup/verifySMS', function(req, res){
emitter.emit("verifySMS", req.body.smsCode);
})
module.exports = router;
答案 0 :(得分:0)
根据上面的代码:
每当您向/
发出get请求时,您就在创建/test
路径。
因此,它第一次起作用是因为/test
路径具有一个处理程序。
第二次或更多时间不起作用,因为,
/test
路由现在具有多个处理程序。 /test
将具有2个处理程序。当您按下/test
时,第一个处理程序将运行。由于这不是中间件,因此不会转到下一个处理程序。现在,第一个处理程序具有与第二个处理程序不同的resolve
函数。因此第二个resolve
函数根本无法运行。(请考虑关闭)对于您打算做什么,大多数Web实施都使用长轮询。因为如果您等待第二条路由的时间太长,则会引发超时错误。意味着您定期打一个api来获取某物的状态。意味着您创建了3条路线。
/signup
/sendsms
/sendsms/check
,您可以在其中传递电话号码。否则,如果您不关心超时,则可以在EventEmitter
路由内使用/test
。
EDIT1:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
const events = require('events');
const emitter = new events.EventEmitter();
let count = 0;
app.get('/', async function (req, res) {
console.log(222);
res.send("Hello!!!");
let check;
try {
console.log(3333);
check = await test();
console.log(4444);
}
catch (err) {
console.log("Error : ", err);
}
console.log(111, check);
});
app.get('/test', function (req, res) {
count = count + 1;
emitter.emit("test",count.toString());
res.send(count.toString());
})
function test(){
return new Promise((res)=>{
emitter.on("test", (data)=>{
res(data);
})
})
}
app.listen(9000, function () {
console.log("hehehehe");
});
EDIT2: 关于解决方案,您需要以不同的方式处理超时。假设您的超时时间是3秒。而SMS路由花了100秒钟来获得响应,或者甚至没有响应。然后您的功能将被卡在那里。
function test(sendSMSTime) {
return new Promise((res, rej) => {
emitter.on("test", (data) => {
.
.
res(data);
})
emitter.on('timeout', rej);//On timeout it will run.
})
}
function timeoutEmitter(timeout) {
setTimeout(() => {
emitter.emit('timeout');
}, timeout)
}
app.post('/signup', async function (req, res) {
try {
timeoutEmitter(3000);
.
.
}catch{
}
});