[英]How to return a resolved promise from an AngularJS Service using $q?
My service is:我的服务是:
myApp.service('userService', [
'$http', '$q', '$rootScope', '$location', function($http, $q, $rootScope, $location) {
var deferred;
deferred = $q.defer();
this.initialized = deferred.promise;
this.user = {
access: false
};
this.isAuthenticated = function() {
this.user = {
first_name: 'First',
last_name: 'Last',
email: 'email@address.com',
access: 'institution'
};
return deferred.resolve();
};
}
]);
I'm calling this in my config
file via:我通过以下方式在我的config
文件中调用它:
myApp.run([
'$rootScope', 'userService', function($rootScope, userService) {
return userService.isAuthenticated().then(function(response) {
if (response.data.user) {
return $rootScope.$broadcast('login', response.data);
} else {
return userService.logout();
}
});
}
]);
However, it complains that then
is not a function.但是,它抱怨then
不是一个函数。 Aren't I returning the resolved promise?我不是在返回已解决的承诺吗?
Resolved promise:已解决的承诺:
return $q.when( someValue ); // angularjs 1.2+
return $q.resolve( someValue ); // angularjs 1.4+, alias to `when` to match ES6
Rejected promise:拒绝承诺:
return $q.reject( someValue );
Return your promise , return deferred.promise.返回您的承诺,返回 deferred.promise。
It is the promise API that has the 'then' method.具有“then”方法的是promise API。
https://docs.angularjs.org/api/ng/service/$q https://docs.angularjs.org/api/ng/service/$q
Calling resolve does not return a promise it only signals the promise that the promise is resolved so it can execute the 'then' logic.调用 resolve 不会返回一个承诺,它只是表明承诺已解决,因此它可以执行“then”逻辑。
Basic pattern as follows, rinse and repeat基本模式如下,冲洗并重复
http://plnkr.co/edit/fJmmEP5xOrEMfLvLWy1h?p=preview http://plnkr.co/edit/fJmmEP5xOrEMfLvLWy1h?p=preview
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js@*" data-semver="1.3.0-beta.5"
src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div ng-controller="test">
<button ng-click="test()">test</button>
</div>
<script>
var app = angular.module("app",[]);
app.controller("test",function($scope,$q){
$scope.$test = function(){
var deferred = $q.defer();
deferred.resolve("Hi");
return deferred.promise;
};
$scope.test=function(){
$scope.$test()
.then(function(data){
console.log(data);
});
}
});
angular.bootstrap(document,["app"]);
</script>
From your service method:从您的服务方法:
function serviceMethod() {
return $timeout(function() {
return {
property: 'value'
};
}, 1000);
}
And in your controller:在您的控制器中:
serviceName
.serviceMethod()
.then(function(data){
//handle the success condition here
var x = data.property
});
Here's the correct code for your service:以下是您的服务的正确代码:
myApp.service('userService', [
'$http', '$q', '$rootScope', '$location', function($http, $q, $rootScope, $location) {
var user = {
access: false
};
var me = this;
this.initialized = false;
this.isAuthenticated = function() {
var deferred = $q.defer();
user = {
first_name: 'First',
last_name: 'Last',
email: 'email@address.com',
access: 'institution'
};
deferred.resolve(user);
me.initialized = true;
return deferred.promise;
};
}
]);
Then you controller should align accordingly:然后你的控制器应该相应地对齐:
myApp.run([
'$rootScope', 'userService', function($rootScope, userService) {
return userService.isAuthenticated().then(function(user) {
if (user) {
// You have access to the object you passed in the service, not to the response.
// You should either put response.data on the user or use a different property.
return $rootScope.$broadcast('login', user.email);
} else {
return userService.logout();
}
});
}
]);
Few points to note about the service:关于服务的几点注意事项:
Expose in a service only what needs to be exposed.在服务中只公开需要公开的内容。 User should be kept internally and be accessed by getters only.用户应该保存在内部,并且只能由 getter 访问。
When in functions, use 'me' which is the service to avoid edge cases of this with javascript.在函数中时,使用“me”服务,以避免使用 javascript 出现这种边缘情况。
I guessed what initialized was meant to do, feel free to correct me if I guessed wrong.我猜到了初始化的目的,如果我猜错了,请随时纠正我。
To return a resolved promise, you can use:要返回已解决的承诺,您可以使用:
return $q.defer().resolve();
If you need to resolve something or return data:如果您需要解决某些问题或返回数据:
return $q.defer().resolve(function(){
var data;
return data;
});
For shorter JavaScript-Code use this:对于较短的 JavaScript 代码,请使用:
myApp.service('userService', [
'$q', function($q) {
this.initialized = $q.when();
this.user = {
access: false
};
this.isAuthenticated = function() {
this.user = {
first_name: 'First',
last_name: 'Last',
email: 'email@address.com',
access: 'institution'
};
return this.initialized;
};
}
]);
You know that you loose the binding to userService.user by overwriting it with a new object instead of setting only the objects properties?您知道通过用新对象覆盖而不是仅设置对象属性来解除对 userService.user 的绑定吗?
Here is what I mean as a example of my plnkr.co example code (Working example: http://plnkr.co/edit/zXVcmRKT1TmiBCDL4GsC?p=preview ):这是我的 plnkr.co 示例代码示例的意思(工作示例: http ://plnkr.co/edit/zXVcmRKT1TmiBCDL4GsC?p=preview):
angular.module('myApp', []).service('userService', [
'$http', '$q', '$rootScope', '$location', function ($http, $q, $rootScope, $location) {
this.initialized = $q.when(null);
this.user = {
access: false
};
this.isAuthenticated = function () {
this.user.first_name = 'First';
this.user.last_name = 'Last';
this.user.email = 'email@address.com';
this.user.access = 'institution';
return this.initialized;
};
}]);
angular.module('myApp').controller('myCtrl', ['$scope', 'userService', function ($scope, userService) {
$scope.user = userService.user;
$scope.callUserService = function () {
userService.isAuthenticated().then(function () {
$scope.thencalled = true;
});
};
}]);
Try this:尝试这个:
myApp.service('userService', [
'$http', '$q', '$rootScope', '$location', function($http, $q, $rootScope, $location) {
var deferred= $q.defer();
this.user = {
access: false
};
try
{
this.isAuthenticated = function() {
this.user = {
first_name: 'First',
last_name: 'Last',
email: 'email@address.com',
access: 'institution'
};
deferred.resolve();
};
}
catch
{
deferred.reject();
}
return deferred.promise;
]);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.