我正在使用Ionic / AngularJS开发一个简单的应用程序,它应该将联系人保存在手机的通讯录中。 我有一个控制器接收联系信息并在检查其存在后保存。这是代码
.controller('SyncCtrl', function($scope, $q, $cordovaSQLite, $ionicLoading, $cordovaContacts, PSFactory) {
...
$scope.findContactsBySearchTerm = function (field, search) {
var opts = {
filter : search,
multiple: true,
fields: [field]
};
//alert('searching for: ' + field + " - " + search);
return $cordovaContacts.find(opts);
}
$scope.addContact = function(order) {
var promises = new Array();
promises.push($scope.findContactsBySearchTerm('emails', order.customer_email));
//promises.push($scope.findContactsBySearchTerm('phoneNumbers', order.customer_phone));
//promises.push($scope.findContactsBySearchTerm('phoneNumbers', order.customer_phone_mobile));
$q.all(promises).then(function(response) {
alert("0: " + JSON.stringify(response[0]));
alert("1: " + JSON.stringify(response[1]));
alert("2: " + JSON.stringify(response[2]));
...
}, function errCb(err){
alert(JSON.stringify(err));
});
};
});
我想检查地址簿中是否已存在联系人,因此我使用$ cordovaContacts.find()方法使用不同的选项(我想检查电子邮件和2个电话号码)。从文档中,这个方法返回一个promise,所以我认为该部分应该是正确的。
问题是,如果我只用1个电话填充promises数组,它就会被解析,我可以输入$ q.all的 then()回调()(此时第二和第三个警报显然是未定义的),但是如果我尝试将其他2个调用放入承诺(取消注释 push()),我不会能够进入然后()回调,我没有警报。 似乎q.all没有等待所有的承诺,因为如果我取消注释 findContactsBySearchTerm()中的alert(),所有代码都像魅力一样!
我对角度和应用程序开发都很陌生,所以我的代码中可能存在错误。请帮我找到.. 任何建议都值得赞赏,甚至是我脚本的整个逻辑
谢谢!
答案 0 :(得分:1)
根据Promises API的.all
,即使其中一个承诺拒绝,它也会拒绝。这可能就是这里发生的事情。
Promise.all失败快速行为
如果其中一个元素被拒绝且Promise.all快速失败,则拒绝Promise.all:如果你有四个在超时后解决的promise,一个拒绝立即,则Promise.all立即拒绝。
参考here
如果你想做出相应的承诺,你应该使用Promise链。您可以使用:
$scope.findContactsBySearchTerm('emails', order.customer_email)
.then( function(responseOfFirstPromise) {
// Do something with your data
if(responseOfFirstPromise.length) { $q.reject(error.emailmatch)}
return $scope.findContactsBySearchTerm('phone', order.customer_phone})
.then(function(responseOfSecondPromise) {
// Do something with your data
})
.done(function() { //handle the result - resolve/reject});