AngularJS非异步发布

时间:2014-05-14 15:35:46

标签: angularjs asynchronous

我有两个$ 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' });
            });
        });
    });

3 个答案:

答案 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' });
            });
        });

    }