use*_*781 11 javascript promise angularjs angular-promise
我正在尝试多次$http调用,我的代码看起来像这样:
var data = ["data1","data2","data3"..."data10"];
for(var i=0;i<data.length;i++){
$http.get("http://example.com/"+data[i]).success(function(data){
console.log("success");
}).error(function(){
console.log("error");
});
}
Run Code Online (Sandbox Code Playgroud)
我怎么能承诺知道所有的$http电话都是成功的?如果其中任何一个失败,将执行一些操作.
die*_*lar 12
你也可以使用$q.all()方法.
所以,从你的代码:
var data = ["data1","data2","data3"..."data10"];
for(var i=0;i<data.length;i++){
$http.get("http://example.com/"+data[i]).success(function(data){
console.log("success");
}).error(function(){
console.log("error");
});
}
Run Code Online (Sandbox Code Playgroud)
你可以这样做:
var promises = [];
data.forEach(function(d) {
promises.push($http.get('/example.com/' + d))
});
$q.all(promises).then(function(results){
results.forEach(function(data,status,headers,config){
console.log(data,status,headers,config);
})
}),
Run Code Online (Sandbox Code Playgroud)
以上基本上意味着执行整个请求并在完成所有请求时设置行为.
使用状态你可以知道是否有任何错误.如果需要,您还可以为每个请求设置不同的配置(例如,可能超时).
$q.all(successCallback, errorCallback, notifyCallback);
Run Code Online (Sandbox Code Playgroud)
如果你想要突破第一个错误,那么你需要让你的for循环同步如下:角度同步http循环来更新进度条
var data = ["data1", "data2", "data3", "data10"];
$scope.doneLoading = false;
var promise = $q.all(null);
angular.forEach(data, function(url){
promise = promise.then(function(){
return $http.get("http://example.com/" + data[i])
.then(function (response) {
$scope.data = response.data;
})
.catch(function (response) {
$scope.error = response.status;
});
});
});
promise.then(function(){
//This is run after all of your HTTP requests are done
$scope.doneLoading = true;
});
Run Code Online (Sandbox Code Playgroud)
如果你想要它是异步的话:如何捆绑Angular $ http.get()调用?
app.controller("AppCtrl", function ($scope, $http, $q) {
var data = ["data1", "data2", "data3", "data10"];
$q.all([
for(var i = 0;i < data.length;i++) {
$http.get("http://example.com/" + data[i])
.then(function (response) {
$scope.data= response.data;
})
.catch(function (response) {
console.error('dataerror', response.status, response.data);
break;
})
.finally(function () {
console.log("finally finished data");
});
}
]).
then(function (results) {
/* your logic here */
});
};
Run Code Online (Sandbox Code Playgroud)
这篇文章也很不错:http://chariotsolutions.com/blog/post/angularjs-corner-using-promises-q-handle-asynchronous-calls/
接受的答案是可以的,但仍然有点难看。您有要发送的东西数组。.而不是使用for循环,为什么不使用Array.prototype.map?
var data = ["data1","data2","data3"..."data10"];
for(var i=0;i<data.length;i++){
$http.get("http://example.com/"+data[i]).success(function(data){
console.log("success");
}).error(function(){
console.log("error");
});
}
Run Code Online (Sandbox Code Playgroud)
这变成
var data = ['data1', 'data2', 'data3', ...., 'data10']
var promises = data.map(function(datum) {
return $http.get('http://example.com/' + datum)
})
var taskCompletion = $q.all(promises)
// Usually, you would want to return taskCompletion at this point,
// but for sake of example
taskCompletion.then(function(responses) {
responses.forEach(function(response) {
console.log(response)
})
})
Run Code Online (Sandbox Code Playgroud)
这使用了更高阶的函数,因此您不必使用for循环,并且看起来也容易得多。否则,它的行为与发布的其他示例相同,因此这纯粹是美学上的变化。
警告对一个词successVS error- success和error更喜欢回调,并警告说,你不知道如何承诺的作品/不正确地使用它。到目前为止,Promise then和Will catch会进行连锁并返回一个新的诺言,将其封装起来,这非常有益。此外,使用success和error(除了的呼叫站点以外的其他任何地方$http)都是一种气味,因为这意味着您显式依赖于Angular HTTP承诺而不是任何符合A +的承诺。
换句话说,尽量不要使用success/ error-很少有他们的理由,他们几乎总是表示代码味道,因为他们介绍的副作用。
关于您的评论:
我在$ q.all上做了自己的非常简单的实验。但是,只有在所有请求都成功时才触发。如果失败了,什么也不会发生。
这是因为合同all是,它要么做出决议,如果每一个承诺是成功的,或者拒绝,如果至少一个是失败的。
不幸的是,Angular的内置$q服务只有all; 如果您希望已拒绝的承诺不会导致最终的承诺被拒绝,那么您将需要使用allSettled,它存在于大多数主要的承诺库中(例如Bluebird和Qkriskowal 的原始库)。另一种选择是自己动手(但我建议蓝鸟)。
| 归档时间: |
|
| 查看次数: |
8886 次 |
| 最近记录: |