我正在努力实现一个能够返回特定用户的所有房间的功能。我正在与firebase
合作并获得一个特定的房间,我写了这个函数:
Db.prototype.getRoom = function (roomUid){
return new Promise(function(resolve, reject) {
firebase.database().ref('rooms/' + roomUid).once('value').then(function(snapshot){
resolve(snapshot.val());
})
});
}
这是我的问题 - 我需要在返回阵列之前下载所有房间。我试过了:
Db.prototype.getUserRooms = function(user){
var rooms = [];
firebase.database().ref('users/' + user.uid + '/rooms')
.once('value').then(function(snapshot){
var roomsIds = snapshot.val() || []; //array of rooms ids
for(var i = 0; i < roomsIds.length; i++){
Db.prototype.getRoom(roomsIds[i]).then(function(room){
rooms.push(room);
});
}
return rooms;
});
}
感谢您的帮助
答案 0 :(得分:2)
你需要做几件事才能完成这项工作。
首先,当您使用for
循环来检索一堆异步值时,您必须收集所有承诺并使用Promise.all()
等待所有这些异步操作完成。
其次,当你在.then()
处理程序中有一个promise时,你需要从.then()
处理程序返回该promise以将它链接在一起。
第三,当你想从另一个方法中调用一个方法时,你需要在对象的实例上调用它,而不是直接在原型上调用它。
// return the inner promise directly rather than wrap in a new promse
Db.prototype.getRoom = function (roomUid){
return firebase.database().ref('rooms/' + roomUid).once('value').then(function(snapshot){
// make the `.val()` result be the fulfilled value of the promise
return snapshot.val();
})
});
}
Db.prototype.getUserRooms = function(user){
var self = this;
return firebase.database().ref('users/' + user.uid + '/rooms').once('value').then(function(snapshot){
var roomsIds = snapshot.val() || []; //array of rooms ids
return Promise.all(roomsIds.map(function(roomID) {
return self.getRoom(roomID);
}));
});
}
他们,我仍然有点困惑为什么你直接在原型上调用方法,例如Db.prototype.getRoom()
。通常,在使用面向对象的Javascript时,您可以在db
对象的实例上调用方法,而不是直接在原型上调用。我已修改getUserRooms()
以这种方式工作,在实例上调用.getRoom()
。
然后,用法如下:
// assumes mydb is an instance of your Db object
mydb.getUserRooms(someUser).then(function(rooms) {
// rooms is an array of rooms
console.log(rooms);
});