2015-11-06 5 views
0

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

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

-- 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' – Bergi

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