我想生成一个唯一的令牌,所以我必须检查MongoDB数据库中是否已存在令牌值。如果令牌已经存在,我正在检查内部条件。虽然在开发模式下我在数据库中只有几个令牌,因此随机值必须生成不同的东西,但是一旦生产,就会有很多令牌。
我的问题是if条件是否等待数据库查询并返回alreadyExists
函数下面的输出?或者是异步,它会再次向下移动generateToken()
?
这是代码,
//Function to check if string already exists
function alreadyExists(val) {
doc.findOne({token: val}).exec(function(err, docObj){
if(!docObj) return 0; //If token not found, send a false
else if (err) return 1; //If error or token, send a false value
else return 1; //If token found, send a true value
});
}
//Function to generate a random token
function generateToken() {
var t = Math.floor(((Math.random() * 9) + 1.111)*1000); //Generates number between 1000 and 9999
if(!alreadyExists(t)) //Check if token not already exists
return t; //Return the token
generateToken(); //Call recursively again until unique token is generated
}
另外,随机代码是否正确?我必须在1111到9999之间生成数字(不包括范围结束,但包括也很好)
答案 0 :(得分:3)
使用Promise
和新的await
/ async
功能来屏蔽。
//Function to check if string already exists
async function alreadyExists(val) {
return new Promise(function(reject, resolve){
doc.findOne({token: val}).exec(function(err, docObj){
if(!docObj) reject(0); //If token not found, send a false
else if (err) reject(err); //If error or token, send a false value
else resolve(1); //If token found, send a true value
});
})
}
//Function to generate a random token
function generateToken() {
var t = Math.floor(((Math.random() * 9) + 1.111)*1000); //Generates number between 1000 and 9999
if(! await alreadyExists(t)) //Check if token not already exists
return t; //Return the token
generateToken(); //Call recursively again until unique token is generated
}
答案 1 :(得分:2)
不,if语句不会等待async函数完成。你必须将回调函数传递给alreadyExists函数
function alreadyExists(val, callback) {
doc.findOne({token: val}).exec(function(err, docObj){
if(!docObj) callback(0); //If token not found, send a false
else if(err) callback(1); //If error or token, send a false value
else callback(1); //If error or token, send a false value
});
}
//Function to generate a random token
function generateToken(callback) {
var t = Math.floor(((Math.random() * 9) + 1.111)*1000); //Generates number between 1000 and 9999
alreadyExists(t, (exists) => {
if(!exists) callback(t); //Check if token not already exists
else generateToken(callback); //Call recursively again until unique token is generated
})
}
或者,您可以使用promises。
答案 2 :(得分:2)
如果要调用异步函数,则应该更多地查看Javascript Promises。现在你的函数已经在if语句中返回undefined,因为它没有时间执行,也就是说你的if语句总是if (!false)
,因为undefined是假的。
将您的其他函数包含在promise中,并使用.then()
表示法来捕获值。
function alreadyExists(val) {
return new Promise((resolve, reject) => {
doc.findOne({token: val}).exec(function(err, docObj){
if(!docObj) resolve(0); //If token not found, resolve falsy value
else if (err) reject(err) //If error reject
else return resolve(1); //If token found, resolve truthy value
});
});
}
//Function to generate a random token
function generateToken() {
var t = Math.floor(((Math.random() * 9) + 1.111)*1000); //Generates number between 1000 and 9999
alreadyExists(t)
.then((value) => {//.then() waits for promise to resolve
if(!value){ //Check if token not already exists
return t; //Return the token
}else{
generateToken(); //Call recursively again until unique token is generated
}
})
.catch((err)=>{
console.log("Error:",err) //catch any thrown errors
})
}