【问题标题】:Determining when nested firebase database ref.on calls have finished确定嵌套的 firebase 数据库 ref.on 调用何时完成
【发布时间】:2019-01-28 12:47:51
【问题描述】:

我的数据库设计(大致)如下:

"users": {
  "userId1": {
    "challenges" {
     "challengeId1"=true,
     "challengeId2"=true
    }
  }, 
  "userId2": {
    "challenges" {
     "challengeId1"=true,
     "challengeId3"=true
    }
  }
  ...
  "userIdN": {...}
}          
"challenges": {
  "challengeId1": {
     "title"="Title 1
    }
  },
  "challengeId2": {
     "title"="Title 2
    }
  },
  "challengeId3": {
     "title"="Title 3
    }
  }
}

在我的客户端中,我进行了以下嵌套调用:

const fetchChallengeList = (currUser) => {
  firebase.database().ref(`/users/${currUser.uid}/challenges`).on('child_added', snapshot => {
    firebase.database().ref(`/challenges/${snapshot.key}`).on('value', snapshotChall => {
      // Dispatch some stuff to UI
    });
  });
};

这通常效果很好,并且可以使所有内容保持同步。使用 .on 可确保每次添加新挑战(到 user:challenges)或修改现有挑战时,firebase 都会更新 UI。

问题在于初始加载。理想情况下,我希望等待更新 UI(例如,显示加载图标),直到用户的现有挑战最初完成加载。否则,用户界面往往会在 5-10 秒的过程中感到震动和扩展。因为调用都是异步的并且保持打开状态,所以我不知道初始集合何时完成加载。有什么方法可以跟踪这个吗?

【问题讨论】:

  • 看看 JavaScript Promise.then
  • 我对 Promise 和 .then 以及 Promise.all 都很熟悉。但我不确定这会把我带到哪里。 .on('child_added') 保持打开状态并为每个(子)挑战返回一个值。你不知道它会先返回多少。即使您这样做了,嵌套的 firebase 回调也会在不同的范围内异步发生。嵌套的回调不知道彼此。所以我看不到使用 Promise 和 .then 的方法。

标签: javascript firebase firebase-realtime-database


【解决方案1】:

我会创建一个方法来显示/隐藏加载器,比如

toggleLoader(display) => {
  // dont know the framework you are using 
  if (display) {
     $('.loader').show();
  } else {       
     $('.loader').hide();
  } 
}

你可以在挑战加载完成后调用这个方法

const fetchChallengeList = (currUser) => {
  firebase.database().ref(`/users/${currUser.uid}/challenges`).on('child_added', snapshot => {
    firebase.database().ref(`/challenges/${snapshot.key}`).on('value', snapshotChall => {
      // Dispatch some stuff to UI
      toggleLoader(false);
    });
  });
};

我还会进行一些错误处理以在出现错误时关闭加载程序。

【讨论】:

  • firebase 调用是异步的。如果有多个挑战,您的答案将在检索到第一个挑战后停止加载程序。
  • 我知道它是异步的,因此代码位于回调中的原因是什么? firebase.googleblog.com/2016/01/…
  • 也许我错过了什么。但是让我们假设我有 3 个挑战。这意味着嵌套的 ref.on 将被调用 3 次,然后包含 toggleLoader 的回调将被调用 3 次。这意味着第一次调用它时,UI 将显示,第二个和第三个回调将准确显示我试图避免的内容。 (我已经使用控制台日志运行代码以确认)。但同样,也许我误解了你的建议。
  • 另外,我不能使用 .then,正如您发送的文章所暗示的那样,因为我正在调用 .on,与 .once 不同,它不会返回 Promise。我需要使用 .on 来确保自动同步对挑战的更改。
  • @Paul 我明白你在说什么。我认为要获得所需的结果很棘手。您可能会做的是从第一个回调中获得 child_added 的总数,并使用 getChildrenCount() 增加一个计数器。一旦它们相等,就关闭加载器。否则我会建议在你的 UI 上使用淡入淡出,以免过渡变得如此跳跃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-30
  • 2019-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多