如何使用promises等待AngularJS forEach中的先前调用结束

时间:2015-11-06 12:07:36

标签: sql-server angularjs foreach promise angular-promise

我遇到了forEach循环的问题,我每次迭代都会调用AngularJS。 Web服务方法调用一个SQL Server存储过程,该过程在表中插入一条记录,如果不存在,我将提供给它的ID。

存储过程是这样的......

-- Other code before

IF (SELECT COUNT(*) FROM Table WHERE TableId = @Id) = 0
    INSERT...

-- Other code after

javascript代码是这样的......

this.callSP = function ($scope, id) {

    return $http({
        url: _spPageContextInfo.webAbsoluteUrl + '/_vti_bin/Project/webservice.svc/Call_SP',
        method: "POST",
        data: {
            "ID": id
        }
    });
};

myArrayOfIds.forEach(function (item) {
    var promise = $WebService.callSP($scope
        , item // id);

    promise.then(function (results) {
        // Do something...            
    }, function (error, status, headers, config) {
        // Do something...
    }).finally(function() {
        // Do something...
    });
});

myArrayOfIds可以包含多个元素,TableId是表的主键,因此有时会发生前两个迭代同时调用存储过程,并且两者都尝试在表中插入记录导致其中一个因主键违规而失败。

有没有等待所有以前的通话结束?

1 个答案:

答案 0 :(得分:0)

我打破了旧的糟糕承诺队列

var PromiseQueue = (function() {
    'use strict';
    var PromiseQueue = function() {
        this.queue = [Promise.resolve(true)];
    };
    PromiseQueue.prototype.add = function(fn) {
        var args = Array.prototype.slice.call(arguments);
        args.shift(); // 
        (function(q, args) {
            q.unshift(function() {
                var done = function() {
                    q.pop();
                    return fn.apply(null, args);
                };
                return q[0].then(done, done);
            }());
        }(this.queue, args));
    };
    return PromiseQueue;
}());

然后可以在您的情况下使用

var pq = new PromiseQueue();

myArrayOfIds.forEach(function (item) {
    pq.add(function (item) {
        var promise = $WebService.callSP($scope, item); // id);

        promise.then(function (results) {
            // Do something...            
        }, function (error, status, headers, config) {
            // Do something...
        }).finally(function() {
            // Do something...
        });
        return promise;
    }, item);
});