2017-02-15 95 views
2

我试着实现将返回所有客房特定用户的功能。我与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; 

     }); 
} 

感谢所有帮助

回答

2

你要做的几件事情,使这项工作。

首先,当你使用一个for循环来检索一堆异步值,你必须收集所有的承诺,并使用Promise.all()等待做所有这些异步操作。其次,如果您在.then()处理程序中有承诺,则需要从.then()处理程序返回该承诺以将其链接在一起。

第三,当你想从另一个方法中调用一个方法,你需要调用它在你的对象的实例,而不是直接在原型。

// 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); 
}); 
+0

这样我的问题的一个干净的解决方案。谢谢 –