我有一个检查数据库中令牌是否存在的函数。问题在于返回bool值需要花费一些时间,我有点需要暂停该函数,以便该函数意识到令牌已存在并再次运行查询。



const registerToken = dispatch => {
  var tokenExisted = null
  do {
    let token = generateRandomToken();
    firebase.database().ref(`/Token`).orderByChild("token").equalTo(token).once("value", snapshot => { // check whether token exists
      if (!snapshot.val()) {  // if token not exist
        token = false;
        // register token to firebase
      } else {
        token = true; // continue the loop to generate a new token and query again
      }
    })
  } while (tokenExisted === true);
}





我的设置基本上是一个do-while循环,当函数第一次被调用时
tokenExisted = null,则将生成一个随机的4位数字令牌,并将一个查询调度到firebase并验证其令牌已存在。

如果令牌已存在,则tokenExisted = true。我希望可以执行该分配,但是Javascript的单线程性质将在查询返回任何内容之前到达循环的结尾。

我想使用setTimeout并每当tokenExisted = null定期添加一些少量时间来保护自己,以便在查询函数返回任何内容时始终捕获该函数。

有没有人有更好的方法来实现同一目标?

最佳答案

这样,您可能需要递归调用函数本身。

const registerToken = dispatch => {
  let token = generateRandomToken();
  const tokenObjectRef = firebase.database().ref(`/Token`);

  tokenObjectRef.orderByChild("token").equalTo(token).once("value")
    .then(snapshot => {
      if (!snapshot.val()) {
        // success!
      } else {
        registerToken(dispatch) // call itself again
      }
    })
    .catch(error => {} ))
}


逻辑是,如果该过程失败并且需要新的查询(如果您需要的话),令牌将在每次新的迭代期间刷新。

注意:避免在do-while逻辑中使用async。由于您可能会遇到很多逻辑错误并且很难跟踪,因此请提前进行仔细计划。

08-06 17:03