AngularJS 承诺从服务返回时不会触发 [英] AngularJS promises not firing when returned from a service

查看:25
本文介绍了AngularJS 承诺从服务返回时不会触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

<块引用>

可能的重复:
angularjs - 承诺永远不会在控制器中解决

我在 AngularJS 服务中封装了一个慢速 WebSockets 服务器,然后从我的控制器调用该服务.如果我将回调链接到回调到回调上,则一切正常,任何 UI 都会异步更新.

当我尝试使用 $q.defer() 来清理那些乱七八糟的回调时,似乎我的 deferred 永远不会被调用.我熟悉 Python 的 Twisted 中延迟的概念,所以我认为从概念上讲,一切都应该可行 - 但事实并非如此.

这是我能想到的最短的例子,慢速 WebSockets 服务器是用 setTimeout 函数模拟的.

<html ng-app="测试版"><头><title>测试版</title><script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js"></script><脚本>var beta = angular.module('beta', []);var BetaCtrl = 函数 ($scope, betaServ) {$scope.button = 函数 () {serv_result = betaServ.slow();控制台日志(serv_result);serv_result.then(函数(结果){console.log('回调完成');});}}beta.service('betaServ', 函数($q) {this.slow = 函数 () {d = $q.defer()设置超时(函数(){console.log('解决前');d.解决();console.log('解决后');}, 2000);返回 d. 承诺;}});<身体><div ng-controller="BetaCtrl"><button ng-click="button()">运行</button>

</html>

可能应该运行如下:

  1. 按钮点击
  2. $scope.button() 被调用;它调用 service.slow() 函数
  3. service.slow() 返回延迟
  4. 在延迟上注册回调
  5. 延迟触发,触发注册的回调(这部分永远不会发生)

有什么想法吗?谢谢.

解决方案

您需要使用 $apply 调用您的回调,因为它是在 Angular 之外调用的.由于这是一项服务,因此您需要在服务中包含 $rootScope:

beta.service('betaServ', function($q, $rootScope) {this.slow = 函数 () {d = $q.defer()设置超时(函数(){console.log('解决前');$rootScope.$apply(d.resolve);console.log('解决后');}, 2000);返回 d. 承诺;}});

Possible Duplicate:
angularjs - promise never resolved in controller

I'm wrapping a slow WebSockets server in a AngularJS service, and then calling into that service from my controllers. If I chain callbacks onto callbacks onto callbacks, everything works just fine, any the UI updates asynchronously.

When I try to use $q.defer() to clean up that mess of callbacks, it seems my deferred never gets called. I'm familiar with the concepts of deferred from Python's Twisted, so I think conceptually everything should work - but it doesn't.

This is the shortest example I could come up with, the slow WebSockets server is simulated with a setTimeout function.

<!doctype html>

<html ng-app="beta">
    <head>
        <title>Beta</title>
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js"></script>
        <script>
            var beta = angular.module('beta', []);

            var BetaCtrl = function ($scope, betaServ) {
                $scope.button = function () {
                    serv_result = betaServ.slow();
                    console.log(serv_result);

                    serv_result.then(function (result) {
                        console.log('callback finished');
                    });
                }
            }

            beta.service('betaServ', function($q) {
                this.slow = function () {
                    d = $q.defer()
                    setTimeout(function () {
                        console.log('before resolve');
                        d.resolve();
                        console.log('after resolve');
                    }, 2000);
                    return d.promise;
                }
            });
        </script>
    </head>
    <body>
        <div ng-controller="BetaCtrl">
            <button ng-click="button()">Run</button>
        </div>    
    </body>
</html>

The could should run as following:

  1. button click
  2. $scope.button() gets called; it calls the service.slow() function
  3. service.slow() returns a deferred
  4. a callback is registered on the deferred
  5. deferred fires, triggering the registered callback (this part never happens)

Any ideas? Thanks.

解决方案

You need to call your callback with $apply since it's called outside of Angular. Since this is a service, you'll need to include $rootScope in your service:

beta.service('betaServ', function($q, $rootScope) {
    this.slow = function () {
        d = $q.defer()
        setTimeout(function () {
            console.log('before resolve');
            $rootScope.$apply(d.resolve);
            console.log('after resolve');
        }, 2000);
        return d.promise;
    }
});

这篇关于AngularJS 承诺从服务返回时不会触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆