Angularjs $q.all [英] Angularjs $q.all

查看:23
本文介绍了Angularjs $q.all的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在 angularjs 中实现了 $q.all,但我无法使代码工作.这是我的代码:

I have implemented the $q.all in angularjs, but I can not make the code work. Here is my code :

UploadService.uploadQuestion = function(questions){

        var promises = [];

        for(var i = 0 ; i < questions.length ; i++){

            var deffered  = $q.defer();
            var question  = questions[i]; 

            $http({

                url   : 'upload/question',
                method: 'POST',
                data  : question
            }).
            success(function(data){
                deffered.resolve(data);
            }).
            error(function(error){
                deffered.reject();
            });

            promises.push(deffered.promise);
        }

        return $q.all(promises);
    }

这是我调用服务的控制器:

And here is my controller which call the services:

uploadService.uploadQuestion(questions).then(function(datas){

   //the datas can not be retrieved although the server has responded    
}, 
function(errors){ 
   //errors can not be retrieved also

})

我认为在我的服务中设置 $q.all 存在一些问题.

I think there is some problem setting up $q.all in my service.

推荐答案

在 javascript 中没有 块级作用域 只有 函数级范围:

In javascript there are no block-level scopes only function-level scopes:

阅读这篇关于 javaScript 范围和提升的文章.

Read this article about javaScript Scoping and Hoisting.

var deferred = $q.defer();
deferred.count = i;

console.log(deferred.count); // 0,1,2,3,4,5 --< all deferred objects

// some code

.success(function(data){
   console.log(deferred.count); // 5,5,5,5,5,5 --< only the last deferred object
   deferred.resolve(data);
})

  • 当你在 for 循环中编写 var deferred= $q.defer(); 时,它被提升到函数的顶部,这意味着 javascript 声明了这个变量在 for 循环 之外的函数作用域上.
  • 对于每个循环,最后一个延迟会覆盖前一个,没有块级作用域来保存对该对象的引用.
  • 当异步回调(成功/错误)被调用时,它们只引用最后一个延迟对象并且只有它被解析,所以$q.all永远不会被解析,因为它仍在等待其他延迟对象.
  • 您需要为您迭代的每个项目创建一个匿名函数.
  • 由于函数确实有作用域,因此即使在执行函数之后,对延迟对象的引用也会保留在闭包作用域中.
  • 正如#dfsq 评论的那样:没有必要手动构造一个新的延迟对象,因为 $http 本身返回一个承诺.
    • When you write var deferred= $q.defer(); inside a for loop it's hoisted to the top of the function, it means that javascript declares this variable on the function scope outside of the for loop.
    • With each loop, the last deferred is overriding the previous one, there is no block-level scope to save a reference to that object.
    • When asynchronous callbacks (success / error) are invoked, they reference only the last deferred object and only it gets resolved, so $q.all is never resolved because it still waits for other deferred objects.
    • What you need is to create an anonymous function for each item you iterate.
    • Since functions do have scopes, the reference to the deferred objects are preserved in a closure scope even after functions are executed.
    • As #dfsq commented: There is no need to manually construct a new deferred object since $http itself returns a promise.
    • 这是一个演示 plunker:http://plnkr.co/edit/NGMp4ycmaCqVOmgohN53?p=preview

      Here is a demo plunker: http://plnkr.co/edit/NGMp4ycmaCqVOmgohN53?p=preview

      UploadService.uploadQuestion = function(questions){
      
          var promises = [];
      
          angular.forEach(questions , function(question) {
      
              var promise = $http({
                  url   : 'upload/question',
                  method: 'POST',
                  data  : question
              });
      
              promises.push(promise);
      
          });
      
          return $q.all(promises);
      }
      

      我最喜欢的方式是使用Array#map:

      这是一个演示 plunker:http://plnkr.co/edit/KYeTWUyxJR4mlU77svw9?p=preview

      UploadService.uploadQuestion = function(questions){
      
          var promises = questions.map(function(question) {
      
              return $http({
                  url   : 'upload/question',
                  method: 'POST',
                  data  : question
              });
      
          });
      
          return $q.all(promises);
      }
      

      这篇关于Angularjs $q.all的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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