检索数据时,javascript+firebase 函数因操作顺序不同导致的return值不正确,如何解决?
How to solve incorrect return value of javascript+firebase function due to order of operation is different when retrieving data?
我目前正在实现一个 javascript 函数来判断用户 ID 和名称是否匹配。
function name_match(user_id, user_realname) {
var dbref = firebase.database().ref();
var namesref = dbref.child("names");
namesref.on("value", function(snapshot) {
snapshot.forEach(i => {
if(i.key == user_id && i.child("realname").val() == user_realname) {
return true;
}
});
});
return false;
}
但是,无论输入如何,它最初都会 return 为假。我认为这是因为它会在加载 firebase 数据时转到 "return false"。
因此,即使最终 return 为真,由于第一次 return 值为假,它会导致这样的问题(在另一个函数中)。
function name_match2() {
var user_id = document.getElementById("user-id").value;
var user_realname = document.getElementById("user-realname").value;
if(!name_match(user_id, user_realname)) return -1;
return 0;
}
它会 return -1.
你能解释一下如何解决这个问题吗?
正如丹尼尔在评论中所解释的那样,外部函数永远不会 returns 为真。异步解决方案可能是这些 :)
function name_match(user_id, user_realname) {
return new Promise(function (resolve, reject) {
var dbref = firebase.database().ref();
var namesref = dbref.child("names");
namesref.on("value", function(snapshot) {
var matched = false;
snapshot.forEach(i => {
if(i.key == user_id && i.child("realname").val() == user_realname) {
matched = true;
}
});
if (matched) {
resolve()
} else {
reject()
}
});
});
}
在调用函数的另一边
name_match('userId', 'userName').then(function(){
//matched
}, function(){
//unmatched
});
其他方法是使用回调:
function name_match(user_id, user_realname, cb) {
var dbref = firebase.database().ref();
var namesref = dbref.child("names");
namesref.on("value", function(snapshot) {
var matched = false;
snapshot.forEach(i => {
if(i.key == user_id && i.child("realname").val() == user_realname) {
matched = true;
}
});
cb(matched);
});
}
在这种情况下:
name_match('userId', 'userName', function(matched) {
console.log(matched);
})
这里是 Suryapratap 解决方案的一个小改编,使用 once()
方法,
- "Listens for exactly one event of the specified event type, and then stops listening.",以及
- Returns一个承诺
... 而不是使用设置侦听器的 on()
方法。
function name_match(user_id, user_realname) {
var dbref = firebase.database().ref();
var namesref = dbref.child("names");
return namesref.once('value').then(function(snapshot) {
var matched = false;
snapshot.forEach(i => {
if(i.key == user_id && i.child("realname").val() == user_realname) {
matched = true;
}
});
return matched;
});
}
我目前正在实现一个 javascript 函数来判断用户 ID 和名称是否匹配。
function name_match(user_id, user_realname) {
var dbref = firebase.database().ref();
var namesref = dbref.child("names");
namesref.on("value", function(snapshot) {
snapshot.forEach(i => {
if(i.key == user_id && i.child("realname").val() == user_realname) {
return true;
}
});
});
return false;
}
但是,无论输入如何,它最初都会 return 为假。我认为这是因为它会在加载 firebase 数据时转到 "return false"。
因此,即使最终 return 为真,由于第一次 return 值为假,它会导致这样的问题(在另一个函数中)。
function name_match2() {
var user_id = document.getElementById("user-id").value;
var user_realname = document.getElementById("user-realname").value;
if(!name_match(user_id, user_realname)) return -1;
return 0;
}
它会 return -1.
你能解释一下如何解决这个问题吗?
正如丹尼尔在评论中所解释的那样,外部函数永远不会 returns 为真。异步解决方案可能是这些 :)
function name_match(user_id, user_realname) {
return new Promise(function (resolve, reject) {
var dbref = firebase.database().ref();
var namesref = dbref.child("names");
namesref.on("value", function(snapshot) {
var matched = false;
snapshot.forEach(i => {
if(i.key == user_id && i.child("realname").val() == user_realname) {
matched = true;
}
});
if (matched) {
resolve()
} else {
reject()
}
});
});
}
在调用函数的另一边
name_match('userId', 'userName').then(function(){
//matched
}, function(){
//unmatched
});
其他方法是使用回调:
function name_match(user_id, user_realname, cb) {
var dbref = firebase.database().ref();
var namesref = dbref.child("names");
namesref.on("value", function(snapshot) {
var matched = false;
snapshot.forEach(i => {
if(i.key == user_id && i.child("realname").val() == user_realname) {
matched = true;
}
});
cb(matched);
});
}
在这种情况下:
name_match('userId', 'userName', function(matched) {
console.log(matched);
})
这里是 Suryapratap 解决方案的一个小改编,使用 once()
方法,
- "Listens for exactly one event of the specified event type, and then stops listening.",以及
- Returns一个承诺
... 而不是使用设置侦听器的 on()
方法。
function name_match(user_id, user_realname) {
var dbref = firebase.database().ref();
var namesref = dbref.child("names");
return namesref.once('value').then(function(snapshot) {
var matched = false;
snapshot.forEach(i => {
if(i.key == user_id && i.child("realname").val() == user_realname) {
matched = true;
}
});
return matched;
});
}