Как дождаться окончания предыдущих звонков в AngularJS forEach с обещаниями

0

У меня проблема с циклом forEach где я называю AngularJS обещанием каждой итерации. Метод веб-службы вызывает хранимую процедуру SQL Server, которая вставляет в таблицу идентификатор, который я ему даю, если он не существует.

Хранимая процедура - это что-то вроде этого...

-- 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 является первичным ключом таблицы, поэтому иногда случается, что первые две итерации одновременно вызывают хранимую процедуру, и оба пытаются вставить запись в таблицу, в результате чего один из них не работает для нарушения первичного ключа.

Стоит ли ждать завершения всех предыдущих вызовов?

  • 0
    Вы хотели, чтобы каждая итерация ожидала завершения предыдущей итерации, прежде чем продолжить?
  • 0
    Ну, просто не используйте forEach . С помощью map вы можете получить обратно массив обещаний и ожидать их всех с помощью $q.all
Показать ещё 3 комментария
Теги:
sql-server
foreach
promise
angular-promise

1 ответ

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);
});

Ещё вопросы

Сообщество Overcoder
Наверх
Меню