我有一个AngularJS应用程序,我使用promises从firebase数据库中获取数据。
这是我的home-controller
:
$scope.wallets;
walletDAO.getWalletsByUserId(auth.uid)
.then(function(wallets){
$scope.wallets = wallets;
$scope.$apply();
})
.catch(function(error){
console.log(error);
});
这是我调用walletDAO
的服务中的两种方法:
this.getWalletsByUserId = function(id) {
return new Promise(function(resolve, reject) {
//codigo aqui
var dbRef = database.ref("users/" + auth.currentUser.uid);
dbRef.on('value', function(data) {
//console.log("Wallet IDs Retrieved!");
var userOnDB = data.val();
var walletIds = userOnDB.wallets;
var wallets = [];
for (i = 0; i < walletIds.length; i++) {
var x = getWalletById(walletIds[i])
.then(function(wallet){
wallets.push(wallet);
})
.catch(function(error){
console.log(error);
});
}
resolve(wallets);
}, function(error) {
reject(error);
});
});
};
var getWalletById = function(id) {
return new Promise(function(resolve, reject) {
var dbRef = database.ref("wallets/" + id);
dbRef.on('value', function(data) {
//console.log("Wallet Retrieved!");
var wallet = data.val();
//console.log(wallet);
resolve(wallet);
}, function(error) {
reject(error);
});
});
};
第二种方法getWalletById
接收钱包ID
并从firebase数据库返回wallet
个对象。这个方法是在getWalletsByUserId
循环内的第一个方法for
上调用的,它应该等待第二个方法在迭代到下一个之前返回钱包,这样它就可以将它推入数组中。问题是它不等待,并且代码在解析.then()
之前在home-controller
上执行getWalletById
方法,使$scope.wallets
为空。
有什么建议吗?
答案 0 :(得分:1)
使用$q.all()
等待所有子承诺完成
$q.all(walletIds.map(function(id){
return getWalletById(id);
})).then(function(wallets){
...
})
答案 1 :(得分:1)
不是使用ref.on方法制作ES6承诺,而是使用ref.once方法并将其带入$q.when的AngularJS执行上下文中:
function getWalletById(id) {
var dbRef = database.ref("wallets/" + id);
var es6Promise = dbRef.once('value');
return $q.when(es6Promise);
}
只有在AngularJS执行上下文中应用的操作才会受益于AngularJS数据绑定,异常处理,属性监视等。
在父函数中使用$q.all和promise chaining:
this.getWalletsByUserId = function(id) {
var dbRef = database.ref("users/" + auth.currentUser.uid);
var es6Promise = dbRef.once('value')
.then(function(snapshot)
//console.log("Wallet IDs Retrieved!");
var userOnDB = snapshot.val();
var walletIds = userOnDB.wallets;
var promiseList = walletIds.map(function(id){
return getWalletById(id);
});
return $q.all(promiseList);
});
return $q.when(es6Promise);
};
.then
方法返回新的承诺,通过successCallback
,errorCallback
的返回值解析或拒绝(除非该值是承诺) ,在这种情况下,使用promise chaining)解析该承诺中解决的值。