关键词:
【中文标题】如何使用 $q 从 AngularJS 服务返回已解决的承诺?【英文标题】:How to return a resolved promise from an AngularJS Service using $q? 【发布时间】:2014-06-27 08:38:21 【问题描述】:我的服务是:
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();
;
]);
我在我的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();
);
]);
但是,它抱怨then
不是一个函数。我不是在返回已解决的承诺吗?
【问题讨论】:
【参考方案1】:如何在 AngularJS 中简单地返回一个预先解决的承诺
已解决的承诺:
return $q.when( someValue ); // angularjs 1.2+
return $q.resolve( someValue ); // angularjs 1.4+, alias to `when` to match ES6
被拒绝的承诺:
return $q.reject( someValue );
【讨论】:
这正是我想要的。存根 http 服务调用时返回静态值的好方法。【参考方案2】:返回你的承诺,返回 deferred.promise。 它是具有 'then' 方法的 promise API。
https://docs.angularjs.org/api/ng/service/$q
调用 resolve 不会返回一个 Promise,它只会发出信号 承诺承诺已解决,因此它可以执行'then'逻辑。
基本模式如下,冲洗一遍重复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>
【讨论】:
那么承诺将如何解决?.then
永远不会被触发
@Shamoon deferred.resolve();在您调用它的那一刻就解决了,因为没有给出任何值。我建议不要写 deferred.resolve("Hi");只需编写 deferred.resolve();得到一个已解决的空头承诺。但你也可以使用 $q.when();得到一个可解决的空承诺;-)。
恕我直言,这比接受的答案要好,后者通过使用 $timeout 生成将要解决的承诺无法显示手动创建和解决承诺的机制。【参考方案3】:
要返回已解决的承诺,您可以使用:
return $q.defer().resolve();
如果您需要解决某些问题或返回数据:
return $q.defer().resolve(function()
var data;
return data;
);
【讨论】:
我有 posted 一个更短的版本。【参考方案4】:对于较短的 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;
;
]);
您知道您通过用新对象覆盖而不是仅设置对象属性来解除与 userService.user 的绑定吗?
以下是我的 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;
);
;
]);
【讨论】:
【参考方案5】:这是您服务的正确代码:
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;
;
]);
那么你的控制器应该相应地对齐:
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();
);
]);
关于服务的几点注意事项:
仅在服务中公开需要公开的内容。用户应保留在内部,并且只能由 getter 访问。
在函数中,使用 'me' 服务来避免 JavaScript 的极端情况。
我猜到了 initialized 的意思,如果我猜错了,请随时纠正我。
【讨论】:
【参考方案6】:来自您的服务方法:
function serviceMethod()
return $timeout(function()
return
property: 'value'
;
, 1000);
在你的控制器中:
serviceName
.serviceMethod()
.then(function(data)
//handle the success condition here
var x = data.property
);
【讨论】:
@BenjaminGruenbaum 是的,你是对的,我不知道$timeout
实际上返回了一个承诺,serviceMethod 可以缩短为:return $timeout(function() return property: 'value' ; , 1000);
这可能有效,但肯定不是推荐的返回承诺的方法
@BenjaminGruenbaum 我做了,现在返回 $timeout 生成的承诺。
很好,我收回了我的-1。
啊好吧,但我仍然同意他的观点,即使出于不同的原因!我很欣赏downvote令人沮丧,我们可以使用upvotes来帮助好的内容浮到顶部,但在这种情况下,我觉得你的回答没有帮助,因为它无法解释 $q 的机制,而是提出$q 的抽象。对 Promise 不熟悉的人,或者像我一样熟悉 Promise 但对 Angular 不熟悉的人,可能会完全搞错!【参考方案7】:
试试这个:
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;
]);
【讨论】:
有人能告诉我为什么这被标记为否决吗?使用 AngularJS 立即返回一个已解决的承诺
】使用AngularJS立即返回一个已解决的承诺【英文标题】:ImmediatelyreturnaresolvedpromiseusingAngularJS【发布时间】:2014-09-0718:53:41【问题描述】:我正在努力理解JavaScript(尤其是AngularJS)中的承诺。我在服务中有一个函数,我们称之为... 查看详情
使用 AngularJS 限制从 Grails Restful 服务返回的数据
】使用AngularJS限制从GrailsRestful服务返回的数据【英文标题】:RestrictingDataReturnedfromaGrailsRestfulServicewithAngularJS【发布时间】:2014-05-2419:50:52【问题描述】:我是使用AngularJS的新手,想使用REST与Grails集成。虽然我找到了很多关于使... 查看详情
如何使用 .success 和 .error 在 Angularjs 中扩展 $q 承诺
】如何使用.success和.error在Angularjs中扩展$q承诺【英文标题】:HowcanIextend$qpromiseinAngularjswitha.successand.error【发布时间】:2013-05-2317:29:34【问题描述】:我在AngularJS的自定义服务中编写了这个小代码。为我服务:vardeferred=$q.defer();va... 查看详情
angularjs$q
1、$q$q是Angular的一种内置服务,它可以使你异步地执行函数,并且当函数执行完成时它允许你使用函数的返回值(或异常)。2、deferdefer的字面意思是延迟, $q.defer() 可以创建一个deferred实例(延迟对象实例)。deferre... 查看详情
AngularJS 使用控制器中的函数从服务中返回数据以用于 ng-repeat
】AngularJS使用控制器中的函数从服务中返回数据以用于ng-repeat【英文标题】:AngularJSuseafunctioninacontrollertoreturndatafromaservicetobeusedinng-repeat【发布时间】:2014-01-2310:31:26【问题描述】:我正在尝试使用控制器中的函数来返回数据,... 查看详情
angularjs中的promise
promise是一种用异步方式处理值的方法,promise是对象,代表了一个函数最终可能的返回值或抛出的异常。在与远程对象打交道非常有用,可以把它们看成一个远程对象的代理。要在Angular中创建promise需要使用内置的$q服务。先用fac... 查看详情
从 angularjs 模态对话服务返回数据
】从angularjs模态对话服务返回数据【英文标题】:returningdatafromangularjsmodaldialogservice【发布时间】:2014-01-2820:35:47【问题描述】:我对AngularJS还很陌生,并且在从模态对话服务返回数据时遇到了问题。基本上,我复制了DanWahlin的... 查看详情
angularjs异步处理$q.defer()
看别人的项目中有用到vardef=$q.defer()返回一个deferred异步对象def当代码逻辑遇到def.resolve(rtns);deferred状态为执行成功,返回rtns为从后台取到的数据,可以继续执行def.then(),def.done()deferred.reject(data);执行到这里时,改变deferred状态为... 查看详情
如何使用 AngularJS 和 Restangular 返回/编辑 REST 资源
】如何使用AngularJS和Restangular返回/编辑REST资源【英文标题】:Howtoreturn/editRESTresourcewithAngularJS&Restangular【发布时间】:2013-06-1916:49:38【问题描述】:在AngularJS中使用Restangular,不断从Mongolab获取一个object对象。我确信它与Promise... 查看详情
如何使用 AngularJS 和 Restangular 返回/编辑 REST 资源
】如何使用AngularJS和Restangular返回/编辑REST资源【英文标题】:Howtoreturn/editRESTresourcewithAngularJS&Restangular【发布时间】:2013-06-1916:49:38【问题描述】:在AngularJS中使用Restangular,不断从Mongolab获取一个object对象。我确信它与Promise... 查看详情
如何使用 PostgreSQL 将数据从 AngularJS 前端传递到 Nodejs 后端?
】如何使用PostgreSQL将数据从AngularJS前端传递到Nodejs后端?【英文标题】:HowtopassdatafromAngularJSfrontendtoNodejsbackendusingPostgreSQL?【发布时间】:2016-12-2905:47:11【问题描述】:使用HTML和AngularJS准备好登录页面和注册页面。我已连接数... 查看详情
从 Promise 内部返回已解决的 Observable
...份验证令牌。(将来可能会使用文件系统)。我的问题是如何从我的http服务返回已解决的承诺,以便我可以订阅组件中的 查看详情
如何模拟在 AngularJS Jasmine 单元测试中返回承诺的服务?
】如何模拟在AngularJSJasmine单元测试中返回承诺的服务?【英文标题】:HowdoImockaservicethatreturnspromiseinAngularJSJasmineunittest?【发布时间】:2014-07-0511:36:08【问题描述】:我有myService使用myOtherService,它进行远程调用,返回承诺:angula... 查看详情
AngularJS $http 从失败的 CORS 请求返回状态码 0
】AngularJS$http从失败的CORS请求返回状态码0【英文标题】:AngularJS$httpreturnsstatuscode0fromfailedCORSrequest【发布时间】:2014-10-1919:10:49【问题描述】:好的,我已经找遍了这个。基本上我们使用的是跨域请求的$http请求。我们的服务器... 查看详情
如何使用angularjs从json文件中获取数据
】如何使用angularjs从json文件中获取数据【英文标题】:howtogetdatafromjsonfileusingangularjs【发布时间】:2014-09-0615:39:13【问题描述】:我正在从json文件中获取数据以显示在表格中,但只有第一次我从getdata()获取数据时,下一次出现... 查看详情
如何使用angularjs
本期更新,博主将给大家分享一些AngularJs常用的一些属性和方法,AngularJS是由Google的员工MiškoHevery从2009年开始着手开发。这是一个非常好的构想,该项目目前已由Google正式支持,有一个全职的开发团队继续开... 查看详情
如何正确地将控制器和服务从 AngularJS 转换为使用 ng-resource
】如何正确地将控制器和服务从AngularJS转换为使用ng-resource【英文标题】:HowtoproperlyconvertcontrollerandservicefromAngularJStousingng-resource【发布时间】:2016-02-2608:26:09【问题描述】:我最近才开始学习ng-resource。我想知道在将我的常规Ang... 查看详情
如何在 AngularJS 中使用 $http.get 从 jsp 页面获取响应?
】如何在AngularJS中使用$http.get从jsp页面获取响应?【英文标题】:Howtogetaresponsefromajsppageusing$http.getinAngularJS?【发布时间】:2018-02-2522:52:50【问题描述】:我是AngularJS中JSON和$http服务的新手。我正在尝试从jsp文件(位于同一文件... 查看详情