尽管有外部声明,但 Firebase 数据库中的变量不会全局显示。(JavaScript)



在过去的几个小时里,我一直在研究局部和全局变量。我从这个问题"如何更改函数内部全局变量的值"以及其他一些问题是,如果变量是在函数之前(在函数外部)声明的,那么当您想更新函数中的变量时,您只需说"变量 = 空白"而没有"var"继续它。

如果您查看下面的功能,我有三个警报,所有警报都通过Firebase提醒当前登录用户的用户名。Firebase 参考中的第一个提醒会显示用户名没有问题。另外两个警报"未定义"。我需要能够在所有三个位置引用变量,我做错了什么吗?或者有没有另一种有效且可能更有效的方法?

var database = firebase.database();
var username;
function initApp() {
// Listen for auth state changes.
// [START authstatelistener]
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
var displayName = user.displayName;
var email = user.email;
var emailVerified = user.emailVerified;
var photoURL = user.photoURL;
var isAnonymous = user.isAnonymous;
var uid = user.uid;
var providerData = user.providerData;
var ref = firebase.database().ref("users/" + uid);
ref.once("value").then(function(snapshot) {
username = snapshot.child("username").val();
alert(username);
});
alert(username);
}
});
}
alert(username);
window.onload = function() {
initApp();
};

我知道这似乎与其他问题相似,但尽管有许多不同的方法,这些答案似乎不起作用。提前感谢您的所有帮助,我希望这只是一个愚蠢的错误。

我认为您对代码的异步性质感到困惑。您的用户名只会在此处的回调中可用:

ref.once("value").then(function(snapshot) {
username = snapshot.child("username").val();
alert(username);
});

因为ref.once("value")是异步的(紧跟在上述代码块之后的alert将始终在执行.then回调之前调用)。任何依赖于username的代码都必须确保异步调用在执行之前完成。

有许多方法可以实现此目的,例如:async/await,从initApp函数返回Promise,或更改initApp以接受在异步内容完成后运行依赖代码的回调。下面是一个返回Promise的示例:

function initApp() {
return new Promise(function(resolve, reject) {
// Listen for auth state changes.
// [START authstatelistener]
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
var displayName = user.displayName;
var email = user.email;
var emailVerified = user.emailVerified;
var photoURL = user.photoURL;
var isAnonymous = user.isAnonymous;
var uid = user.uid;
var providerData = user.providerData;
var ref = firebase.database().ref("users/" + uid);
ref.once("value").then(function(snapshot) {
username = snapshot.child("username").val();
resolve(username);
});
} else {
// no username, reject
reject("User is not logged in")
}
});
});
}
window.onload = function() {
initApp().then(function(username) {
alert(username);
// do things that depend on user/username
}).catch(function(error) {
alert(error);
});
};

一旦Promise到位,就可以使用 async/await 来使代码感觉更加同步:

window.onload = async function() {
try {
const username = await initApp();
alert(username);
} catch(e) {
alert(e);
}
};

请记住,您仍然无法在此函数之外alert用户名 - 任何依赖于异步数据的代码都必须等到该数据准备就绪,即在then/callback/等中处理。

相关内容

  • 没有找到相关文章

最新更新