我有一个检查数据库中令牌是否存在的函数。问题是返回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
以保护安全,以便在查询函数返回任何内容时函数将始终捕获。
有没有人有更好的方法来实现同样的目标?
答案 0 :(得分:1)
递归调用函数。
function get_token_then(callback_when_token_found) {
firebase.database().etc.etc(function (data) {
if (data == what_you_want) {
callback_when_token_found(data);
} else {
// You might want to wrap this in setTimeout in order to throttle your database calls
get_token_then(callback_when_token_found);
}
}
}
答案 1 :(得分:1)
您可能希望以递归方式调用函数本身。
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
。仔细地提前计划,因为您可能会遇到很多逻辑错误并且很难追踪。