我正在ionic
框架中开发一个应用程序。
我在控制器中有一个功能,应该下载facebook个人资料图片,如下所示($rootScope.user_friends
是对象的数组,其中对象的fb_id属性中有用户的脸谱ID,其个人资料图片将被下载):
$scope.downloadDP = function() {
// Make an API call for getting facebook profile picture URL
Session.userFBProfilePicture($rootScope.user_friends, function(response) {
console.log(response);
});
};
以下是服务/工厂方法:
// Makes API call for user's facebook DP URL
userFBProfilePicture: function(data_array, callback) {
var promises = [];
for (var i = 0; i < data_array.length; i++) {
var deffered = $q.defer();
var data = data_array[i];
$http({
method: 'GET',
url: 'https://graph.facebook.com/' + data.fb_id + '/picture?type=large&redirect=false',
}).
success(function(data) {
var url = data.url;
var targetPath = cordova.file.applicationStorageDirectory + "MyApp/" + data.mobile + ".png";
var trustHosts = true;
var options = {};
$cordovaFileTransfer.download(url, targetPath, options, trustHosts)
.then(function(result) {
deffered.resolve(result);
}, function(err) {
deffered.reject();
});
}).
error(function(error) {
deffered.reject();
});
promises.push(deffered);
}
return $q.all(promises);
},
成功进行https://graph.facebook.com/' + data.fb_id + '/picture?type=large&redirect=false
网址的网络调用,而不是服务器重定向,我得到一个data.url
给出用户个人资料图片实际位置的对象。
我参考了这篇博客文章:https://www.raymondcamden.com/2015/04/13/chaining-multiple-cordova-file-transfers-with-ngcordova/并试图相应地宣传,但徒劳无功。
另外,我在控制器方法中console.log(response);
没有得到任何结果。我不确定我哪里出错,任何帮助/指针都非常感激。
答案 0 :(得分:2)
我更喜欢使用async库进行数据库或api调用等异步操作。
所以功能就像
// Makes API call for user's facebook DP URL
userFBProfilePicture: function(data_array, callback) {
var results_array= [];
var deffered = $q.defer();
async.each(data_array, function(data, callback) {
$http({
method: 'GET',
url: 'https://graph.facebook.com/' + data.fb_id + '/picture?type=large&redirect=false',
}).
then(function(data) {
var url = data.url;
var targetPath = cordova.file.applicationStorageDirectory + "MyApp/" + data.mobile + ".png";
var trustHosts = true;
var options = {};
$cordovaFileTransfer.download(url, targetPath, options, trustHosts)
.then(function(result) {
results_array.push(result);
callback();
}, function(err) {
callback(err);
});
}, function(error) {
callback(error);
});
}, function(err){
// if any of the input produced an error, err would equal that error
if( err ) {
// One of the iterations produced an error.
// All processing will now stop.
return deffered.reject(err);
} else {
return deffered.resolve(results_array);
}
})
return deffered.promise;
},
此函数将返回一个承诺。所以你可以相应地处理它。
答案 1 :(得分:1)
当我查看$ http文档时,这是我看到的示例。
// Simple GET request example:
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
也许试试.then
?
.success
方法是我不熟悉的方法吗?如果这不是主题,而是在查看代码时我的第一个想法,请道歉。
编辑刚刚在here上看到了这一点。
弃用通知$ http遗留承诺方法成功与错误 已被弃用。请改用标准方法。如果 $ httpProvider.useLegacyPromiseExtensions设置为false然后这些 方法将抛出$ http / legacy错误。
感谢。
答案 2 :(得分:1)
我认为问题在于您如何在控制器级别解决承诺,您正在以回调方式处理它。正确的实施应该是
Session.userFBProfilePicture($rootScope.user_friends)
.then(function(response) {
console.log(response);
// bind the data.url to the scope or View Model and use ng-src in your view
})
.catch(function(err) {
// handle error
});
此外,@ jamesmpw是正确的,您应该使用带有$ http的.then
承诺结构来避免遗留错误。