Javascript 在AngularJS服务中使用承诺

Javascript 在AngularJS服务中使用承诺,javascript,angularjs,Javascript,Angularjs,我正在将一些代码从Silverlight迁移到AngularJS。我的Silverlight代码基本上会尝试访问web服务。如果失败,它将稍等片刻,然后重试。它会尝试这三次。我现在试着用AngularJS做这个 根据我的理解,我应该使用AngularJS服务来访问我的web服务。据我理解,承诺是被使用的。目前,我有以下服务: 'use strict'; myApp.service('$myService', function($rootScope, $http) { this.queryAt

我正在将一些代码从Silverlight迁移到AngularJS。我的Silverlight代码基本上会尝试访问web服务。如果失败,它将稍等片刻,然后重试。它会尝试这三次。我现在试着用AngularJS做这个

根据我的理解,我应该使用AngularJS服务来访问我的web服务。据我理解,承诺是被使用的。目前,我有以下服务:

'use strict';
myApp.service('$myService', function($rootScope, $http) {
  this.queryAttempt = 0;
  this.findRecent = function() {
    this.queryAttempt = 0;
  };

  this.attemptToGetRecent = function() {
    try {
      this.queryAttempt = this.queryAttempt + 1;
      if (this.recentQueryAttempt < 3) {
        $http.get('http://www.someserver.com/endpoint');        
      } else {
        console.log('signal failure');
      }
    } catch (ex1) {
      console.log('Error Finding Recent (2).');
    }
  };
});
“严格使用”;
myApp.service(“$myService”,函数($rootScope,$http){
this.queryattent=0;
this.findRecent=函数(){
this.queryattent=0;
};
this.attemptToGetRecent=函数(){
试一试{
this.queryattest=this.queryattest+1;
如果(此.recentquery尝试<3){
$http.get('http://www.someserver.com/endpoint');        
}否则{
控制台日志(“信号故障”);
}
}捕获(ex1){
log('查找最近的错误(2)。');
}
};
});
由于承诺被使用,我有点迷茫。在Silverlight中,我创建了事件。我的控制器将调用$myService.findRecent()。我想检测成功和失败。但是,我还需要一些重试逻辑。如果我不需要重试逻辑,我只需要在findRecent函数中使用return$http.get(…)。但是,由于重试逻辑的需要,我不知道如何构造我的承诺,以便控制器知道a)成功,b)如果尝试了三次,但失败了,那么控制器会知道失败


有人能告诉我如何在承诺的世界里解决这个问题吗?

让我在下面的评论中发布代码:

myApp.service('myService', function($rootScope, $http, $q) {

    var findRecent - function() {

        var deferred = $q.defer();

        attemptToGetRecent(0, deferred);

        return deferred.promise;
    };


    var attemptToGetRecent = function(count, deferred) {
        $http.get('http://www.someserver.com/endpoint')
             .success(function (response) {
                deferred.resolve(response);
             })
             .error(function() {
                if (count >= 3) {
                    deferred.reject();
                } else {
                    attemptToGetRecent(count++, deffered);
                }
             });
    };
});
  • 在您的服务get
    $q
    服务实例中,创建延迟对象 (承诺)你自己
  • 将其作为参数传递给
    attemptoGetRecent
    函数,该函数将 不断递归地调用自己,直到努力的次数过多为止 高
  • 函数
    attemptotoGetRecent
    将尝试调用服务器,如果 成功它解决了你的承诺与数据。如果呼叫失败, 它将被再次调用最多3个计时器,然后拒绝您的承诺
  • 此代码的使用者将以以下方式使用它:

    myService.findRecent()    
        .then(function (data) {
            console.log(data);
            $scope.videos = data.feed.entry;
          }, function() {
            console.log("error");
          });       
        }; 
    
    为了便于阅读,我删除了控制台日志记录。当然可以加上。另外,最好不要用前导$命名您自己的服务,这是为angular服务保留的

    工作示例:

    您可以注入$q并使用它来做出自己的承诺,并创建一个递归函数来处理这些尝试

    以下是一些应该有帮助的代码:

    'use strict';
    myApp.service('$myService', function ($rootScope, $http, $q) {
        this.getRecent = function(){
            var deferred = $q.defer();
            var attempts = 0;
            (function queryRecent(attempts, error){
                if(attempts >= 2){
                    // the $http.get() failed 3 times
                    deferred.reject(error);
                }else{
                    $http.get('http://www.someserver.com/endpoint').then(function(response){
                        // success -> resolve any data you want
                        deferred.resolve({
                            attempts: attempts,
                            response: response
                        });
                    }).catch(function(error){
                        // failed, retry the queryRecent recursive function
                        queryRecent(attempts + 1, error); // pass attempts + 1 and the error object
                    });
                }
            })(attempts, ''); // initially pass 0 and '' to the queryRecent recursive function
            return deferred.promise;
        };
    });
    
    myApp.controller('MyCtrl', function($scope, $myService){
        $myService.getRecent().then(function(data){
            // success -> use data
            console.log(data);
        }).catch(function(error){
            // the $http.get() failed 3 times
            console.log(error);
        });
    });
    

    当我执行这段代码时,我得到一个未处理的异常。这与消费者代码有关。服务代码似乎工作得很好。但是,在使用者中不会调用.success |错误代码。我只是在控制台窗口中看到“undefined不是一个函数”。我在findRecent函数中输入了deferred。代码的其余部分似乎还可以。请调试它,并检查到底什么是未定义的,或者如果你可以提供小提琴。谢谢在发布评论之前,我已经修复了延迟的错误。不幸的是,我似乎无法让调试器告诉我什么是未定义的。我现在在打电话,如果有帮助的话,我明天可以为你创建工作小提琴。代码中有一些拼写错误。我编辑了我的答案并添加了工作示例。链接是: