AngularJs $ q.defer()不起作用

时间:2014-08-23 15:18:34

标签: javascript angularjs promise

我在$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;
        });
    }
);

它有效。
非工作代码和工作代码之间有什么区别?

2 个答案:

答案 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