我有两个$ http帖子,每个帖子都在一个循环中发布对象数组。问题是第二个$ http帖子依赖于第一个完成的帖子。有没有办法让他们不是异步电话?我试图使用延迟,但它有些错误,因为它不起作用。当标签保存正在进行时,它仍会激活组保存。
角:
var deferred = $q.defer();
var all = $q.all(deferred.promise);
for (var property in data.tagAdded) {
if (data.tagAdded.hasOwnProperty(property)) {
$http({
method: "POST",
url: '/api/projects/' + data.Project.Id + '/tags',
data: ({ Name: data.tagAdded[property].tag.Name })
}).success(function (response) {
deferred.resolve(response);
data.tagAdded[property].tag.Id = response.Data[0].Id;
data.tagAdded[property].tag.ProjectId = response.Data[0].ProjectId;
}).error(function (response) {
tagError = true;
$.jGrowl("Error saving new tags. Contact support.", { header: 'Error' });
});
}
}
deferred.promise.then(function() {
console.log(data);
});
all.then(function() {
groups.forEach(function(group) {
$http({
headers: { 'Content-Type': 'application/json; charset=utf-8' },
method: "POST",
url: '/api/projects/' + data.Project.Id + '/recruiting-groups',
data: angular.toJson(group, false)
}).success(function(response) {
}).error(function(response) {
recError = true;
$.jGrowl("Error saving recruiting group. Contact support.", { header: 'Error' });
});
});
});
答案 0 :(得分:1)
没有承诺完全不是你想要做的。事实上,这正是承诺闪耀最多的情况!基本上,您没有正确使用$q.all
。您可以将一个承诺列表传递给它,并在它们全部解决后解决。如果其中任何一个失败,它将产生被拒绝的承诺,其拒绝与第一个失败的承诺相同。您当然可以通过.catch
调用来拒绝拒绝,该调用返回除$q.reject
值以外的任何内容。
我用承诺重新实现了你所拥有的东西。 .success
和.error
都相当有限,所以我在这里使用了传统的.then
和.catch
方法。
/**
* Here we define a function that takes a property, makes a POST request to
* create a tag for it, and then appends the promise for the request to a list
* called tagRequests.
*/
var tagRequests = [];
var createTag = function(property) {
tagRequests.push($http({
method: "POST",
url: '/api/projects/' + data.Project.Id + '/tags',
data: ({ Name: data.tagAdded[property].tag.Name })
}).then(function(response) {
var responseData = response.data;
data.tagAdded[property].tag.Id = responseData.Data[0].Id;
data.tagAdded[property].tag.ProjectId = responseData.Data[0].ProjectId;
return responseData;
}).catch(function (err) {
var errorMsg = "Error saving new tags. Contact support.";
$.jGrowl(errorMsg, { header: 'Error' });
// If we don't want the collective promise to fail on the error of any given
// tag creation request, the next line should be removed.
return $q.reject(errorMsg);
}));
};
/**
* We then iterate over each key in the data.tagAdded object and invoke the
* createTag function.
*/
for (var property in data.tagAdded) {
if (Object.prototype.hasOwnProperty.call(data.tagAdded, property)) {
createTag(property);
}
}
/**
* Once all tag requests succeed, we then map over the list of groups and
* transform them into promises of the request being made. This ultimately
* returns a promise that is resolved when all group POST requests succeed.
*/
$q.all(tagRequests)
.then(function(tagsCreated) {
return $q.all(groups.map(function(group) {
return $http({
headers: { 'Content-Type': 'application/json; charset=utf-8' },
method: "POST",
url: '/api/projects/' + data.Project.Id + '/recruiting-groups',
data: angular.toJson(group, false)
}).then(function(response) {
return response.data;
})
.catch(function(err) {
var errorMsg = "Error saving recruiting group. Contact support.";
$.jGrowl(errorMsg, { header: 'Error' });
// If we want this collective promise to not fail when any one promise is
// rejected, the next line should be removed.
return $q.reject(errorMsg);
});
}));
});
我强烈建议一般来看一下Promises,然后再看一下$ q文档。我还写了this blog post关于承诺在Angular中的工作方式以及它们与大多数承诺实现的区别。
答案 1 :(得分:0)
这正是承诺所做的。 Angular使用Kris Kowal's Q库来承诺。查看the Angular docs页面,有一个完美的承诺模式示例。基本上你会做第一次电话,然后一旦它的承诺返回成功,就进行第二次电话会议。
答案 2 :(得分:0)
我不得不改变我的代码,让一些同事团队工作。我完全没有承诺。
我使用计数器跟踪计数器= 0时通过添加到计数器然后成功/失败我从计数器减少为每个完成的事务将其反向。当计数器为0时我就完成了,然后拨打我的下一位$ http post。 Angular Deferred:
var counter = 0;
var tags = [];
for (var property in data.tagAdded) {
if (data.tagAdded.hasOwnProperty(property)) {
tags.push({ Name: property });
}
}
if (tags.length == 0) {
groupInsert();
} else {
tags.forEach(function (tag) {
counter ++;
$http({
method: "POST",
url: '/api/projects/' + data.Project.Id + '/tags',
data: ({ Name: tag.Name })
}).success(function (response) {
console.log(response)
counter--;
data.tagAdded[property].tag.Id = response.Data[0].Id;
data.tagAdded[property].tag.ProjectId = response.Data[0].ProjectId;
if (counter == 0) {
groupInsert();
}
}).error(function (response) {
counter--;
tagError = true;
$.jGrowl("Error saving new tags. Contact support.", { header: 'Error' });
if (counter == 0) {
groupInsert();
}
});
});
}
function groupInsert() {
groups.forEach(function (group) {
console.log(group)
$http({
headers: { 'Content-Type': 'application/json; charset=utf-8' },
method: "POST",
url: '/api/projects/' + data.Project.Id + '/recruiting-groups',
data: angular.toJson(group, false)
}).success(function (response) {
}).error(function (response) {
recError = true;
$.jGrowl("Error saving recruiting group. Contact support.", { header: 'Error' });
});
});
}