У меня проблема с циклом 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
является первичным ключом таблицы, поэтому иногда случается, что первые две итерации одновременно вызывают хранимую процедуру, и оба пытаются вставить запись в таблицу, в результате чего один из них не работает для нарушения первичного ключа.
Стоит ли ждать завершения всех предыдущих вызовов?
Я вырву свою старую дерьмовую очередь ожидания
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);
});
forEach
. С помощьюmap
вы можете получить обратно массив обещаний и ожидать их всех с помощью$q.all