Angularjs $q.all [英] Angularjs $q.all
本文介绍了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 thefor 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屋!
查看全文