我有一个factory
,它在获取json文件时向我提供了一个承诺:
myapp.factory('topAuthorsFactory', function($http, $q) {
var factory = {
topAuthorsList: false,
getList: function() {
var deffered = $q.defer();
$http.get('../../data/top_10_authors.json')
.success(function(data, status) {
factory.topAuthorsList = data;
}).error(function(data, status) {
deffered.reject('There was an error getting data');
});
return deffered.promise;
}
};
return factory;
});
并在我的controller
中,我想在控制台上显示json
文件的内容,如下所示:
myapp.controller('topAuthorsController', function($scope, topAuthorsFactory) {
$scope.listAuthors = topAuthorsFactory.getList().then(function(topAuthorsList) {
$scope.listAuthors = topAuthorsList;
console.log('Testing...');
}, function(msg) {
alert(msg);
});
console.log($scope.listAuthors);
}
但是在我的控制台中我得到了这个:
那我怎么解决这个问题呢?为什么我没有看到消息"测试......"在控制台?
答案 0 :(得分:5)
收到回复后,您应该解决承诺。
deferred.resolve(data)
理想情况下,您不应该遵循您正在进行的方法,在您处理已经返回承诺的$http.get
时,创建新承诺被视为反模式,您可以利用该承诺。所以基本上你需要清理你的工厂。通过返回$http.get
对象& .then
功能,(also .success
& .error
methods are deprecated)。当收到数据时,第一个功能将接到电话。否则错误功能将被调用。基本上为了解决或拒绝承诺,您需要从promise返回数据,这将调用.then
方法的后续caller
函数。
<强>工厂强>
myapp.factory('topAuthorsFactory', function($http) {
var factory = {
topAuthorsList: false,
getList: function() {
//returning promise
return $http.get('../../data/top_10_authors.json')
.then(function(response) {
var data = response.data;
factory.topAuthorsList = data;
//returning data to resolving promise
return data;
}, function(error) {
return 'There was an error getting data';
});
}
};
return factory;
});
修改强>
基本上你已经将工厂方法调用topAuthorsFactory.getList()
分配给$scope.listAuthors
方法,这里不需要,然后你打印$scope.listAuthors
变量,它显然会有promise对象。所以你应该删除那个任务,&amp; $scope.listAuthors
函数将分配.then
值。
<强>控制器强>
//remove $scope.listAuthors assignment which is incorrect.
topAuthorsFactory.getList().then(function(topAuthorsList) {
$scope.listAuthors = topAuthorsList;
console.log('Testing...');
}, function(msg) {
alert(msg);
});
它的异步将在异步调用完成时评估其函数。console.log
语句
答案 1 :(得分:1)
试试这个:
.success(function(data, status) {
factory.topAuthorsList = data;
deffered.resolve(data);
}).error(function(data, status) {
deffered.reject('There was an error getting data');
});
您必须解决获取数据的承诺。
答案 2 :(得分:1)
第一个问题是您立即记录了承诺本身,而不是它的分辨率值。第二,你甚至不能在getList
中解决退回的承诺。试试这个:
getList: function() {
return $http.get('../../data/top_10_authors.json').then(function(response) {
return response.data;
}, function() {
throw 'There was an error getting data';
});
}
// ...
$scope.listAuthors = null;
topAuthorsFactory.getList().then(function(topAuthorsList) {
$scope.listAuthors = topAuthorsList;
console.log('Testing...');
console.log($scope.listAuthors);
}, function(msg) {
alert(msg);
});
我注意到您在使用$http
时使用了explicit promise construction antipattern。 $http
已经返回了一个承诺,这比success
和error
回调更受青睐。我改进了getList
函数以使用承诺链。
你可以找到一些关于使用promises的教程: