使用 Promise 从 Angularjs 中的 JSON 文件读取数据
Reading data from JSON file in Angularjs using a Promise
我有一个 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);
}
但在我的控制台中我得到了这个:
那我该如何解决呢?为什么我在控制台中看不到 "testing..." 消息?
试试这个:
.success(function(data, status) {
factory.topAuthorsList = data;
deffered.resolve(data);
}).error(function(data, status) {
deffered.reject('There was an error getting data');
});
您必须履行获取数据的承诺。
您应该在收到回复后解决 promise。
deferred.resolve(data)
理想情况下,你不应该遵循你正在做的方法,当你处理已经 return 承诺的 $http.get
时,创建新的承诺被认为是反模式,你可以利用那个承诺。所以基本上你需要清理你的工厂。通过 returning $http.get
对象和 .then
函数,(also .success
& .error
methods are deprecated)。 then 的第一个函数将在收到数据时被调用,否则错误函数将被调用。基本上,为了解决或拒绝承诺,您需要 return 来自承诺的数据,这将调用 caller
方法的后续 .then
函数。
工厂
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 对象。所以你应该删除那个分配,& $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
语句
第一个问题是您立即记录了承诺本身,而不是它的解析值。第二个是你甚至没有解决 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
已经 returns 一个承诺,并且比 success
和 error
回调更受欢迎。我改进了您的 getList
函数以使用承诺链。
您可以找到一些使用 promises 的教程:
- An SO answer by myself
- promisejs.org
- toptal.com
- html5rocks.com
我有一个 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);
}
但在我的控制台中我得到了这个:
那我该如何解决呢?为什么我在控制台中看不到 "testing..." 消息?
试试这个:
.success(function(data, status) {
factory.topAuthorsList = data;
deffered.resolve(data);
}).error(function(data, status) {
deffered.reject('There was an error getting data');
});
您必须履行获取数据的承诺。
您应该在收到回复后解决 promise。
deferred.resolve(data)
理想情况下,你不应该遵循你正在做的方法,当你处理已经 return 承诺的 $http.get
时,创建新的承诺被认为是反模式,你可以利用那个承诺。所以基本上你需要清理你的工厂。通过 returning $http.get
对象和 .then
函数,(also .success
& .error
methods are deprecated)。 then 的第一个函数将在收到数据时被调用,否则错误函数将被调用。基本上,为了解决或拒绝承诺,您需要 return 来自承诺的数据,这将调用 caller
方法的后续 .then
函数。
工厂
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 对象。所以你应该删除那个分配,& $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
语句
第一个问题是您立即记录了承诺本身,而不是它的解析值。第二个是你甚至没有解决 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
已经 returns 一个承诺,并且比 success
和 error
回调更受欢迎。我改进了您的 getList
函数以使用承诺链。
您可以找到一些使用 promises 的教程:
- An SO answer by myself
- promisejs.org
- toptal.com
- html5rocks.com