在if条件下调用异步JS函数

时间:2017-08-28 05:04:52

标签: javascript mongodb

我想生成一个唯一的令牌,所以我必须检查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之间生成数字(不包括范围结束,但包括也很好)

3 个答案:

答案 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
  })
}