我有这段代码检查用户是否已在Firebase中登录,如果是,请使用Redux调度操作并将状态更新为当前的auth用户。
/**
* check to see if the user has signed in already or not
*/
function initAuth(dispatch) {
return new Promise((resolve, reject) => {
const unsubscribe = firebase.auth().onAuthStateChanged(
authUser => {
dispatch({ type: "INIT_AUTH", payload: authUser });
unsubscribe();
resolve();
},
error => reject(error)
);
});
}
initAuth(store.dispatch)
.then(() => render())
.catch(error => console.error(error));
我感到困惑的是,为什么在取消订阅中调用unsubscribe()?我知道你可以像在JavaScript递归中那样做,但这里有什么用?谢谢!
答案 0 :(得分:6)
onAuthStateChanged
接受一个函数,因为它是唯一的参数。该函数是在auth状态更改时将调用的函数。所以代码
function printHelloWorld() {
console.log("Hello World")
}
firebase.auth().onAuthStateChanged(printHelloWorld)
只要auth状态发生变化,就会将"Hello World"
打印到控制台。但是,在稍后的某个时间,我们希望停止执行该功能,因为我们已经做了我们需要的任何事情。如果您熟悉事件侦听器,他们会使用模式删除一个,您可以调用removeEventListener
之类的内容。但firebase没有offAuthStateChanged
或其他类似的东西。相反,onAuthStateChanged
函数会向您返回一个函数,该函数取消订阅您最初提供的函数。要清楚,它不会返回您的原始函数(您提供的函数,因此在此示例中为printHelloWorld
),但会返回一个 new 函数,可用于删除原始函数
回到这个例子:
function printHelloWorld() {
console.log("Hello World")
}
var unsubscribe = firebase.auth().onAuthStateChanged(printHelloWorld)
// ... Sometime later when we are no longer interested in auth changes
unsubscribe();
// From this point forward, when the auth state changes, printHelloWorld will no longer be triggered.
最后,假设您只想让auth更改运行一个函数,但只运行一次。最简单的方法是让它运行一次,然后取消订阅。所以代码:
var unsubscribe = firebase.auth().onAuthStateChanged(() => {
console.log("Hello World")
unsubscribe()
})
表示第一次使用auth状态更改时,我们将记录该字符串,然后立即取消订阅进一步的更改。因此,通过在函数本身中调用取消订阅,我们只是说,运行一次,然后删除自己。
另外,请注意您可以在功能的开头或结尾调用取消订阅,这并不重要。整个函数体将像其他任何一样执行。所以调用unsubscribe不会停止执行函数的其余部分,或类似的事情。
这就是
这样的原因var unsubscribe = firebase.auth().onAuthStateChanged(() => {
unsubscribe()
// Lots of other code here...
});
是一种常见的模式。
答案 1 :(得分:1)
如果只想一次监听用户身份验证状态的变化,则必须采用以下方式:
const unsubscribe = firebase.auth().onAuthStateChanged((user) => {
if(unsubscribe) {
unsubscribe();
}
}
似乎侦听器运行两次,第一次是在创建时,第二次是在用户实际更改其状态时。第一次没有定义unsubscribe
,因此您在运行之前检查是否已定义。