需要以串行方式运行ajax调用,然后在角度

时间:2016-07-28 18:04:21

标签: angularjs ajax

我有一系列id。

var myArray = [1,2,32,42,5];

我需要做的是在每个id上以串行方式执行ajax调用。如何完成所有操作后再运行另一个功能?

现在,因为我正在做forEach我很确定它并行运行。

myArray.forEach(function(item) {
    $http({
      method: 'POST',
      url: '/someUrl/' + item,
      data: {'some' : 'data'}
    })
});

   $scope.reloadUsers();

2 个答案:

答案 0 :(得分:0)

如果你真的如你所说,需要连续运行承诺,那么你可以这样做:

function postItems(items) {
    var results = [];

    return items
        .reduce(function (last, cur) {
            return last.then(function (result) {
                if (result) { results.push(result); }

                return $http({
                    method: 'POST',
                    url: '/someUrl/' + cur,
                    data: {'some' : 'data'}
                });
           });
       }, $q.resolve())
       .then(function (result) {
           if (result) { results.push(result); }

           return results;
       });
}

postItems(myArray).then(function () { return $scope.reloadUsers(); });

如果您实际上不需要POST操作的结果,那么postItems可以大大简化:

function postItems(items) {
    return items
        .reduce(function (last, cur) {
            return last.then(function (result) {
                return $http({
                    method: 'POST',
                    url: '/someUrl/' + cur,
                    data: {'some' : 'data'}
                });
           });
       }, $q.resolve())
}

您还可以创建可重用的实用程序函数以串行方式运行promises,然后获取结果。上面的第一种方法将成为:

function runPromiseSerial(values, action) {
    var results = [];

    if(values.length === 0) { return $q.resolve(results); }

    var start = $q.resolve();

    return values
        .reduce(function (last, cur) {
            return last.then(function (result) {
                if (last !== start) { results.push(result); }

                return action(cur);
            });
       }, start)
       .then(function (result) {
           results.push(result);

           return results;
       });
}

function postItems(items) {
    return runPromiseSerial(items, function (item) {
        return $http({
            method: 'POST',
            url: '/someUrl/' + item,
            data: {'some' : 'data'}
        });            
    });
}

postItems(myArray).then(function () { return $scope.reloadUsers(); });

答案 1 :(得分:0)

您可以使用jQuery的延迟对象链接异步调用,例如ajax调用,并使用'then'。

$(function() {
    var delay = 3000,
        span = $('span'),
        posts = [1,2,32,42,5],
        asyncFunction = function(data) {
            var deferred = $.Deferred();

            setTimeout(function() {
                span.append('Argument:<br />');
                span.append(data + '<br />');

                $('span').append('Waiting ' + delay + ' milliseconds<br /><br />');

                deferred.resolve();
            }, delay);

            return deferred.promise();
        },
        looper = $.Deferred().resolve();

    $.each(posts, function(i, data) {
        looper = looper.then(function() {
            return asyncFunction(data);
        });
    });
});

您可以在Fiddle上观看示例。但是Ajax被替换为超时功能

希望这会有所帮助

小提琴使用此代码

复制下面的代码以观察它适用于您的方案。

.news-block {
  position: relative;
  width: 300px;
  background: green;
  height: 700px;
  overflow: hidden;
}
.news-block img {
  position: absolute;
  top: -120px;
  transition: top 1s;
}
.news-block:hover {
  background: yellow;
}
.news-block:hover img {
  top: 20px;
  transition: top 1s;
}