Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在我自己的Angular服务中,如何将返回值返回给调用该服务的控制器?_Javascript_Angularjs_Http_Service_Promise - Fatal编程技术网

Javascript 在我自己的Angular服务中,如何将返回值返回给调用该服务的控制器?

Javascript 在我自己的Angular服务中,如何将返回值返回给调用该服务的控制器?,javascript,angularjs,http,service,promise,Javascript,Angularjs,Http,Service,Promise,我很难理解angular中$http中的成功和错误回调以及承诺的“then”部分。$http服务返回一个承诺。“success”回调是“then”回调的一个例子吗? 如果我在自己的服务中插入$http怎么办?我该怎么做 我认为代码更容易显示我的问题: app.controller('MainCtrl', function ($scope, $log, BooksService) { BooksService.retrieveAllBooks().then(function(results

我很难理解angular中$http中的成功和错误回调以及承诺的“then”部分。$http服务返回一个承诺。“success”回调是“then”回调的一个例子吗? 如果我在自己的服务中插入$http怎么办?我该怎么做

我认为代码更容易显示我的问题:

app.controller('MainCtrl', function ($scope, $log, BooksService) {
    BooksService.retrieveAllBooks().then(function(results) {
      $scope.allBooks = results;
    });
  });


app.factory('BooksService', function($http,$log) {
  var service = {
    retrieveAllBooks: function() {
      return $http({
        method: 'GET','https://hugebookstore.org/allbooks'
        headers: {
            "Content-Type": "application/json",
            "Accept": "application/json"
        }
      }).success(function(data, status, headers, config) {
         var allbooks = transformDataIntoBooksArray(data);//this function exists and just takes raw data and turns them into Book objects
         return allbooks;/*how is this "success" callback related to the "then"() callback in app.controller above?*/
      };
      }).error(function(data, status, headers, config) {
        $log.error('here is an error'+data + status + headers + config);
      });
    }
  };
  return service;
});
有关
应用程序控制器的问题
代码:

我是否需要在
app.controller中使用
“then()”
函数?

我只想让我的控制器使用
图书服务
给我一份所有图书的列表。
bookservice
已经有了一个“
then
”类型的子句,即“
success
”回调。似乎我有一个不必要的“
然后
”。这是真的吗

另外,何时调用“
then
”,我可以在
then的
回调函数的参数中添加任何内容吗

我不明白默认情况下提供了哪些参数以及我可以添加什么

有关
应用程序工厂的问题
代码:

首先,这是我理解代码要做的事情

我正在使用factory()方法而不是Angular中可用的service()方法创建一个
BooksService
。 我正在定义一个名为
retrieveAllBooks()
的函数,它在后台使用Angular中的$http发出异步GET请求,这本身就是一个服务
RetrieveAllBooks()
只不过是$http GET服务的包装器,这使得客户端可以轻松地调用
BooksService.RetrieveAllBooks()
并获得一组Book对象

什么时候执行“
success
”回调,它与我的
app.controller中的“
then
”回调有什么关系?

我的
success
()回调中的
return
值似乎从未返回到
app.controller
。为什么?

如何将allbooks数组返回到app.controller(最初称为
BooksService.retrieveAllBooks()
)中

success
回调中是否允许任何其他参数

我需要从
retrieveAllBooks
()函数定义返回什么?我是单独返回
$http promise
,还是需要
从成功和
错误
回调中返回一些东西

我知道这很冗长,但我希望有人能帮助我,b/c这一模式——将我的网络调用分离到自己的
服务
层,而不是直接在我的
控制器
层中调用$
http
,这将一次又一次地进行


谢谢

成功
和错误处理程序特定于
$http
返回的承诺。但是,它们类似于
。然后(函数onFulfill(){},函数onReject(){})

这取决于你是否想直接回报承诺或实施其他东西

通常,控制器不应该关心服务如何处理请求。因此,在我看来,你不应该直接回报这个承诺。只需处理服务中的成功和错误案例。如果请求成功,则返回结果;如果请求失败,则抛出错误

然后,您可以在控制器中使用泛型
.then(函数onFulfill(){},函数onReject(){})
模式,因为这在Angular中总是有效的,并且是预期的

onFulfill
回调始终将您的结果作为参数接收,
onReject
回调将错误作为参数接收

那么,你有什么选择?在您的服务中删除
.success
.error
回调,并在控制器中处理成功案例中的转换,或者创建新的延迟承诺以返回转换结果:

app.factory('BooksService', function($http,$log,$q) {
  var service = {
    retrieveAllBooks: function() {
      var deferred = $q.defer();
      $http({
        method: 'GET','https://hugebookstore.org/allbooks'
        headers: {
            "Content-Type": "application/json",
            "Accept": "application/json"
        }
      }).success(function(data, status, headers, config) {
         var allbooks = transformDataIntoBooksArray(data);//this function exists and just takes raw data and turns them into Book objects
         deferred.resolve( allbooks );
      };
      }).error(function(data, status, headers, config) {
        $log.error('here is an error'+data + status + headers + config);
        deferred.reject( new Error( 'here is an error'+data + status + headers + config );
      });
      return deferred.promise;
    }
  };
  return service;
});
尽管如此,如果我们考虑到: -误差已经由角度传感器跟踪 -延期付款是多余的,可以避免 -内容类型和接受由Angular和serer生成。 -我们可以保存匿名包装器以进行操作

因此,我们最终得出以下结论:

app.factory('BooksService', function($http) {
  return {
    retrieveAllBooks: function() { 
      return $http.get('https://hugebookstore.org/allbooks').
             then(transformDataIntoBooksArray); // Error tracked by Angular already
      }
    }
});

奥利弗,谢谢你。我绝对同意控制器不必做任何转换,而应该交给书籍数组。看起来我将接受您的实现,我需要阅读$q和defer()方法。出于某种原因,我认为$q在angular(yikes!)的最新版本中不再需要了,或者肯定是一种高级用法,在我的“常用用例”中也不再需要,所以我对它进行了掩饰。“成功和错误处理程序……只是语法上的糖分超过了实现。然后(…)”。抱歉,这不是真的。
.success()
.error()
保证返回其原始输入承诺,而
.then()
保证返回一个新承诺,其值/原因由执行的处理程序(如果有)决定<因此,
.then()
具有
.success()
.error()
各自不具备的“过滤”能力。Angular文档不善于说明这一点。再加上@Roamer-1888所说的,您不需要延迟返回$http返回一个承诺。如果您使用
。那么
只需返回结果承诺并使用返回值即可。