我在$q.defer();
时遇到了一些问题
当我使用回调时,我的代码正在运行(视图已更新),但是 $q.defer();
则没有
这是我的代码:
服务:
eventsApp.factory('eventData', function($http, $q) {
return {
getEvent: function(callback) {
var deferred = $q.defer();
$http({method: 'GET', url: '/node/nodejsserver/server.js'}).
success(function(data, status, headers, config){
//callback(data.event);
deferred.resolve(data.event);
console.log('status: ', status, ' data: ', data);
}).
error(function(data, status, headers, config){
deferred.reject(status);
console.log('status: ', status);
});
return deferred.promise;
}
};
});
控制器:
eventsApp.controller('EventController',
function EventController($scope, eventData) {
$scope.event = eventData.getEvent();
}
);
但它不起作用。
然后我找到了this answer,我更新了我的控制器:
eventsApp.controller('EventController',
function EventController($scope, eventData) {
eventData.getEvent().then(function(result) {
$scope.event = result;
});
}
);
它有效。
非工作代码和工作代码之间有什么区别?
答案 0 :(得分:11)
非工作代码使用自动承诺展开,在最近的Angular版本中已弃用和删除。它被认为太神奇了。
当您返回承诺时,Angular用于执行以下操作:
这种行为被Angular开发人员认为令人困惑和神奇,并且在Angular中被弃用(在1.2中),停用并很快(1.3)被删除。通过承诺分配值的正确方法就像您在第二个示例中指出的那样:
eventData.getEvent().then(function(result) {
$scope.event = result;
});
来自Angular 1.3(待定)发布文档:
$ parse:由于fa6e411d,承诺展开已被删除。它自1.2.0-rc.3以来已被弃用。它无法再打开。已删除两种方法:
来自1.2版本的文档:
$ parse和模板一般不再自动解包承诺。
在:
$scope.foo = $http({method: 'GET', url: '/someUrl'});
<p>{{foo}}</p>
后:
$http({method: 'GET', url: '/someUrl'})
.success(function(data) {
$scope.foo = data;
});``
{{FOO}}
`
此功能已被弃用。如果绝对需要,可以通过$ parseProvider.unwrapPromises(true)API重新启用它。
虽然我们在这里避免the deferred anti pattern,但$http
已经返回了承诺,因此您只需return
而不是$q.defer
。
答案 1 :(得分:1)
编辑:查看本杰明的回答
在您的服务中,您将返回promise
个对象,promise对象具有.then
方法。
您要将promise
对象分配给$scope.event
,因此您无法获取数据(根据Benjamin的最新版本)
当您使用deferred.resolve(data.event)
解析承诺时,将使用此已解析数据调用您作为参数传递给.then
方法的函数。
您可以为.then
提供第二个参数,当您执行deferred.reject()
这是promise api的基本功能。只需阅读文档了解更多信息https://docs.angularjs.org/api/ng/service/ $ q