2015-11-06 59 views
0

我在forEach循环中遇到问题,我在每次迭代时都会调用AngularJS的承诺。 Web服务方法调用一个SQL Server存储过程,该过程将在表中插入记录的ID存储在不存在的ID中。如何等待以前的调用在AngularJS for each中承诺

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

-- 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',你可以得到一个promise数组,并用'$ 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); 
});