我有这段代码可以检查用户是否已经在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中调用unsubscribe()?我知道您可以像在JavaScript递归中那样进行操作,但是这里有什么用?谢谢!

最佳答案

onAuthStateChanged接受一个函数,因为它是唯一的参数。该函数是每当auth状态更改时将调用的函数。所以代码

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

firebase.auth().onAuthStateChanged(printHelloWorld)

每当身份验证状态更改时,都会将"Hello World"打印到控制台。但是,稍后,我们希望停止执行该函数,因为我们已经完成了所需的任何操作。如果您熟悉事件监听器,那么它们会使用一种模式来删除事件监听器,您将调用removeEventListener之类的东西。但是firebase没有offAuthStateChanged或类似的代码。而是onAuthStateChanged函数向您返回一个函数,该函数取消订阅您最初给它的函数。需要明确的是,它不会返回原始函数(在此示例中为您提供的原始函数,因此为printHelloWorld),但会为您返回一个可用于删除原始函数的新函数。

回到示例:
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...
});

是这样一种常见的模式。

09-16 15:34