【发布时间】:2016-11-18 11:42:05
【问题描述】:
让我们想象一个使用 Angular 和 Firebase 开发的网络应用。 在这个应用程序中,有一个页面,其中包含公共事件列表(从 Firebase 检索)显示为开关元素列表。 用户可以通过切换开关来注册/取消注册每个事件,它会自动更新他自己注册的事件列表(更新用户 Firebase db 的每个开关上的 ng-change)。
所以我创建了一个数据库服务:
//private
var eventList = [];
// methods
this.getEventList = function(){
if(eventList.length > 0){
console.info('[getEventList] Event list already fetched');
return eventList;
}
else{
console.info('[getEventList] Event list has never been fetched');
this.loadEventList();
}
}
this.loadEventList = function(){
console.info('[LoadEventList] Fetch event list');
var events = [];
firebase.database().ref('events/').once('value').then(function(snap) {
snap.forEach(function(item) {
events.push({
id: item.val().id,
name: item.val().name,
registered: false
});
});
console.info('[LoadEventList] End of fetching');
console.dir(events);
eventList = events;
return eventList;
});
}
还有一个用户服务,我在其中编写了一个函数,该函数允许将用户注册到的事件列表与公共事件的全局列表同步。我想显示公共事件的完整列表以及根据用户所做的注册来切换的开关:
this.syncEventListWithUserEventss = function(listToSync){
userRef.child('events/').once('value', function(snap){
var userEvents = snap.val();
// sync only if user registered at least one event
if(userEvents) {
for(var i = 0; i < userEvents.length; i++){
for(var j = 0; j < listToSync.length; j++){
if(listToSync[j].id ==userEvents[i]){
listToSync[j].registered = true;
}
}
}
}
});
}
到目前为止,我的代码运行良好。但它在页面控制器中变得很棘手:
function ($scope, $stateParams, DatabaseService, UserService) {
$scope.events = [];
console.info('[Ctrl] Before getEventList()');
console.dir($scope.events);
$scope.events = DatabaseService.getEventList();
console.info('[Ctrl] After getEventList()');
console.dir($scope.events);
UserService.syncEventListWitEventports($scope.events);
$scope.updateUserEventList = UserService.updateUserEventList;
}])
结果:
[Ctrl] Before getEventList()
Array[0]
[getEventList] Event list has never been fetched
[LoadEventList] Fetch event list
[Ctrl] After getEventList()
undefined
[LoadEventList] End of fetching
Array[4]
所以这是我的问题:
- 我的第一个呼叫 (getEventList) 是否阻塞?这意味着 console.info('[Ctrl] After getEventList()');直到 getEventList() 完成才被执行?
- 如何使我的 loadEventList() 调用阻塞,以便我的控制器在事件列表完全加载并传递给控制器之前不会执行任何进一步的代码
- 满足这些需求的最佳做法是什么
谢谢!
【问题讨论】:
-
使用回调或返回 Promise
-
这不是我通过调用 loadEventList 所做的,其中 return 语句嵌套在 promise 中吗?在我的情况下有什么具体的解决方案吗?谢谢
-
你在 loadEventList 中使用了一个 promise,但是那个函数没有返回任何东西,最好在那里传递一个回调。
-
回调方法 -
this.getEventList = function(cb){/this.loadEventList(cb);/this.loadEventList = function(cb){/return eventList;tocb(eventList);/DatabaseService.getEventList(function(data) {$scope.events = data; }); -
确实效果更好!非常感谢!
标签: javascript angularjs firebase firebase-realtime-database