我怎样才能创建一项 returns 价值承诺的服务
How can I create a service that returns the value promise
我想创建一个 returns json
的服务
或者通过请求到服务器,或者通过检查它是否已经存在于:Window.content
但我不想从我的控制器那里得到承诺!
我想要 json 准备好!
几种方式我都试过几次
我尝试使用 with then
方法在我的服务中进行测试
但我还是得到了承诺
(是否只带$http
,是否带$q
)
如果我的 Controller 没有承诺,我无法获得该值
我的服务:
app.service('getContent',['$http', function( $http ){
return function(url){ // Getting utl
if(window.content){ // if it's the first loading, then there is a content here
var temp = window.content;
window.content = undefined;
return temp;
}
return $http.get(url);
};
}]);
我的控制器:
.state('pages', {
url: '/:page',
templateProvider:['$templateRequest',
function($templateRequest){
return $templateRequest(BASE_URL + 'assets/angularTemplates/pages.html');
}],
controller: function($scope, $stateParams, getContent){
// Here I want to to get a json ready :
$scope.contentPage = getContent(BASE_URL + $stateParams.page + '?angular=pageName');
}
});
这是不可能的。如果负责计算或检索值的代码依赖于承诺,您将无法 return 您的函数从承诺中提取的值。
解释:这个从控制流程上很容易看出来。一个承诺是异步评估的。从服务器检索 json 可能需要几秒钟,但您函数的调用者不应该等待这么久,因为您的整个运行时环境会阻塞。这就是您首先使用承诺的原因。 Promises 只是组织回调的好方法。所以当你的 promise returns 时,导致函数调用的事件已经终止。其实必须有,不然你的承诺无法评价。
你想错了。服务总是 returns 承诺,因为没有从 API:
获取 JSON 的同步方式
app.factory('myService', ['$http', function($http) {
return $http('http://my_api.com/json', function(resp) {
return resp.data;
});
}]);
然后您可以在您的控制器中这样调用它:
app.controller('myController', ['$scope', 'myService', function($scope, myService) {
myService.then(function(data) {
$scope.contentPage = data; // here is your JSON
}, function(error) {
// Handle errors
});
}]);
如果数据存在,只需在promise中解决即可。
虽然这个过程仍然是异步的,但它不需要网络调用并且 returns 很快。
app.service('getContent',['$http', '$q', function( $http, $q ){
return function(url){
// create a deferred
var deferred = $q.defer();
if(window.content){ // if it's the first loading, then there is a content here
var temp = window.content;
window.content = undefined;
deferred.resolve(temp); // resolve the data
return deferred.promise; // return a promise
}
// if not, make a network call
return $http.get(url);
};
}]);
重申一下,这是异步的,但不需要网络调用。
您的服务正在返回当前写入的承诺。承诺永远是承诺,因为你真的不知道它什么时候会完成。然而,对于 Angular 的 2 路数据绑定,这不是问题。请参阅下面我的编辑以及 docs
中 $HTTP
的示例
在你的控制器中
controller: function($scope, $stateParams, getContent){
getContent(BASE_URL + $stateParams.page + '?angular=pageName')
.then(aSuccessFn, aFailedFn);
function aSuccessFn(response) {
// work with data object, if the need to be accessed in your template, set you scope in the aSuccessFn.
$scope.contentPage = response.data;
}
function aFailedFn(data) {
// foo bar error handling.
}
}
我想创建一个 returns json
的服务或者通过请求到服务器,或者通过检查它是否已经存在于:Window.content
但我不想从我的控制器那里得到承诺!
我想要 json 准备好!
几种方式我都试过几次
我尝试使用 with then
方法在我的服务中进行测试
但我还是得到了承诺
(是否只带$http
,是否带$q
)
如果我的 Controller 没有承诺,我无法获得该值
我的服务:
app.service('getContent',['$http', function( $http ){
return function(url){ // Getting utl
if(window.content){ // if it's the first loading, then there is a content here
var temp = window.content;
window.content = undefined;
return temp;
}
return $http.get(url);
};
}]);
我的控制器:
.state('pages', {
url: '/:page',
templateProvider:['$templateRequest',
function($templateRequest){
return $templateRequest(BASE_URL + 'assets/angularTemplates/pages.html');
}],
controller: function($scope, $stateParams, getContent){
// Here I want to to get a json ready :
$scope.contentPage = getContent(BASE_URL + $stateParams.page + '?angular=pageName');
}
});
这是不可能的。如果负责计算或检索值的代码依赖于承诺,您将无法 return 您的函数从承诺中提取的值。
解释:这个从控制流程上很容易看出来。一个承诺是异步评估的。从服务器检索 json 可能需要几秒钟,但您函数的调用者不应该等待这么久,因为您的整个运行时环境会阻塞。这就是您首先使用承诺的原因。 Promises 只是组织回调的好方法。所以当你的 promise returns 时,导致函数调用的事件已经终止。其实必须有,不然你的承诺无法评价。
你想错了。服务总是 returns 承诺,因为没有从 API:
获取 JSON 的同步方式app.factory('myService', ['$http', function($http) {
return $http('http://my_api.com/json', function(resp) {
return resp.data;
});
}]);
然后您可以在您的控制器中这样调用它:
app.controller('myController', ['$scope', 'myService', function($scope, myService) {
myService.then(function(data) {
$scope.contentPage = data; // here is your JSON
}, function(error) {
// Handle errors
});
}]);
如果数据存在,只需在promise中解决即可。
虽然这个过程仍然是异步的,但它不需要网络调用并且 returns 很快。
app.service('getContent',['$http', '$q', function( $http, $q ){
return function(url){
// create a deferred
var deferred = $q.defer();
if(window.content){ // if it's the first loading, then there is a content here
var temp = window.content;
window.content = undefined;
deferred.resolve(temp); // resolve the data
return deferred.promise; // return a promise
}
// if not, make a network call
return $http.get(url);
};
}]);
重申一下,这是异步的,但不需要网络调用。
您的服务正在返回当前写入的承诺。承诺永远是承诺,因为你真的不知道它什么时候会完成。然而,对于 Angular 的 2 路数据绑定,这不是问题。请参阅下面我的编辑以及 docs
中$HTTP
的示例
在你的控制器中
controller: function($scope, $stateParams, getContent){
getContent(BASE_URL + $stateParams.page + '?angular=pageName')
.then(aSuccessFn, aFailedFn);
function aSuccessFn(response) {
// work with data object, if the need to be accessed in your template, set you scope in the aSuccessFn.
$scope.contentPage = response.data;
}
function aFailedFn(data) {
// foo bar error handling.
}
}