简体   繁体   English

Firebase onAuthStateChanged取消订阅递归

[英]Firebase onAuthStateChanged unsubscribe recursion

I have this code that checks to see if a user is already signed in in Firebase, if so, use Redux to dispatch an action and update the state to the current auth user. 我有这段代码可以检查用户是否已经在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));

What I am confused is, why is the unsubscribe() called within the unsubscribe? 我感到困惑的是,为什么在unsubscribe中调用unsubscribe()? I know you can do this as in JavaScript recursion, but what's the use here? 我知道您可以像在JavaScript递归中那样进行操作,但是这里有什么用? Thanks! 谢谢!

onAuthStateChanged takes a function as it's only argument. onAuthStateChanged采用一个函数,因为它是唯一的参数。 That function is the one that will be invoked whenever the auth state changes. 该函数是在auth状态更改时将被调用的函数。 So the code 所以代码

function printHelloWorld() {
    console.log("Hello World")
}

firebase.auth().onAuthStateChanged(printHelloWorld)

Will print "Hello World" to the console, any time the auth state changes. 每当身份验证状态更改时,都会在控制台上打印"Hello World" But, at some later time, we want to stop that function from executing anymore, because we've already done whatever we need to. 但是,稍后,我们希望不再执行该函数,因为我们已经完成了所需的任何操作。 If you're familiar with event listeners, they use a pattern where to remove one, you would call something like removeEventListener . 如果您熟悉事件侦听器,则它们会使用一种模式来删除事件侦听removeEventListener ,您将调用removeEventListener东西。 But firebase does not have a offAuthStateChanged or some such. 但是offAuthStateChanged没有offAuthStateChanged或类似的东西。 Instead the onAuthStateChanged function returns a function to you that unsubscribes the function you originally gave it . 而是onAuthStateChanged函数向您返回一个函数,该函数取消订阅您最初给它的函数 To be clear, it does not return your original function (the one you gave it, so printHelloWorld in this example), but returns you a new function that can be used to remove the original. 需要明确的是,它不会返回原始函数(您给了它的那个函数,因此在此示例中为printHelloWorld ),而是返回了一个可用于删除原始函数的函数。

So going back to the example: 回到示例:

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.

Finally, suppose that you only want to have a function run on auth changes, but only one time . 最后,假设您只想让一个函数在auth更改上运行,但运行一次 The simplest way to do that would be to have it run once, then unsubscribe it. 最简单的方法是先运行一次,然后取消订阅。 So the code: 所以代码:

var unsubscribe = firebase.auth().onAuthStateChanged(() => {
    console.log("Hello World")
    unsubscribe()
})

means that the first time auth state changes, we will log the string, then immediately unsubscribe from further changes. 意味着第一次身份验证状态更改时,我们将记录该字符串,然后立即取消订阅进一步的更改。 So by calling the unsubscribe from within the function itself, we are just saying, run one time, then remove yourself. 因此,通过在函数内部调用取消订阅,我们只是说,运行一次,然后删除自己。

Also, note that you can call unsubscribe at the beginning or end of the function, it doesn't matter. 另外,请注意,您可以在函数的开头或结尾调用取消订阅,这没关系。 The entire function body will execute, just like any other. 整个函数主体将像其他函数一样执行。 So calling unsubscribe won't halt the execution of the remainder of the function, or anything like that. 因此,调用unsubscribe不会停止执行该函数的其余部分,或者类似的事情。

This is why things like 这就是为什么像

var unsubscribe = firebase.auth().onAuthStateChanged(() => {
    unsubscribe()
    // Lots of other code here...
});

is such a common pattern. 是这样的常见模式。

If you want to listen for the changes in the auth status of the user just one time you have to do it this way: 如果你想监听的用户只是一个时间 ,你必须这样做,这样的权威性地位的变化:

const unsubscribe = firebase.auth().onAuthStateChanged((user) => { 
    if(unsubscribe) {
      unsubscribe();
    }
 }

It seems the listener runs twice, the first time when is created, and second time when the user actually changes his status. 侦听器似乎运行两次,第一次是在创建时,第二次是在用户实际更改其状态时。 In the first time the unsubscribe is not defined so you to check that is defined before run it. 第一次没有定义unsubscribe因此您在运行前检查是否已定义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM