【问题标题】:Firebase onAuthStateChanged unsubscribe recursionFirebase onAuthStateChanged 取消订阅递归
【发布时间】:2018-04-13 01:57:47
【问题描述】:

我有这段代码可以检查用户是否已经在 Firebase 中登录,如果是,请使用 Redux 调度一个操作并将状态更新到当前的身份验证用户。

/**
 * 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 递归中那样做,但是这里有什么用呢?谢谢!

【问题讨论】:

    标签: javascript firebase recursion redux firebase-authentication


    【解决方案1】:

    onAuthStateChanged 接受一个函数作为它的唯一参数。该函数是在身份验证状态更改时将调用的函数。所以代码

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

    只要身份验证状态发生变化,就会将"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.
    

    最后,假设您只想让一个函数在身份验证更改时运行,但只有一次。最简单的方法是让它运行一次,然后取消订阅。所以代码:

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

    表示首次身份验证状态更改时,我们将记录该字符串,然后立即取消订阅进一步的更改。因此,通过从函数本身调用取消订阅,我们只是说,运行一次,然后删除自己。

    另外,请注意,您可以在函数的开头或结尾调用取消订阅,没关系。整个函数体将像其他函数一样执行。所以调用 unsubscribe 不会停止函数其余部分的执行,或者类似的事情。

    这就是为什么

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

    是一种很常见的模式。

    【讨论】:

    • 还是没听懂哈哈...你能详细说明一下吗?就像另一个例子一样?如果在解决之前调用取消订阅,为什么解决仍然有效?
    • 在我的帖子中详细阐述了很多。希望这可以消除任何困惑,但如果您仍有疑问,请发表评论。
    • 吃完饭回来看到这么详细的回答很惊讶,现在真的很清楚了,谢谢!
    • "onAuthStateChanged 接受一个函数作为它的唯一参数。"在撰写本文时可能是正确的,但它需要 1-3 个参数、成功、错误和取消订阅。
    • @nilloc 随意编辑答案以反映最新版本的 firebase 工作方式。我已经有一段时间没有使用 firebase 了,所以我有点落伍了。
    【解决方案2】:

    如果你想监听用户身份验证状态的变化一次你必须这样做:

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

    似乎侦听器运行了两次,第一次是在创建时,第二次是在用户实际更改其状态时。第一次没有定义unsubscribe,所以你在运行它之前检查它是否已经定义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-06
      • 2021-03-23
      • 1970-01-01
      相关资源
      最近更新 更多