我有一个工厂方法,如下所示:
angular.module('GridSamplesApp')
.factory('registerPostFactory', function($resource, $q, WebRequest) {
var getMessage = function(Upddata, token, dataurl)
{
var deferred = $q.defer();
var settings = {
data: Upddata,
headers: {
'Content-Type': 'application/JSON',
'x-csrf-token' : token
},
method: 'POST',
url: dataurl,
withCredentials: true
};
WebRequest.requestRaw(settings).then(
function(response) {
// data from app sec
var msg = response;
deferred.resolve(msg);
},
function(error) {
console.log('Error retrieving message', error);
deferred.reject('Error retrieving message', error);
});
return deferred.promise;
};
return {
getMessage: getMessage
};
});
我有一个看起来像
的控制器$scope.getLogs = function()
{
$.each($scope.modifiedSN, function(i, e) {
if ($.inArray(e, result) == -1) result.push(e);
});
$scope.inputs.push({SN:'', Key:'', status:'', log:''});
for(var i=0; i<result.length; i++)
{
var j = result[i];
if ($scope.data[j].SerialNumber !== "")
{
var Upddata = {};
Upddata['IConvRuleFlg'] = '';
Upddata['SrNum'] = $scope.data[j].SerialNumber;
Upddata['LvEmailId'] = 'abc@xyz.com';
Upddata['WKey'] = $scope.data[j].WtyKey;
registerPostFactory.getMessage(Upddata, $scope.token, dataurl).then(
function(response) {
$scope.msg = response.headers["custommessage"];
$scope.data[j].AutolinkErrorlog = $scope.msg;
$scope.inputs.push({SN: $scope.data[j].SerialNumber, Key: $scope.data[j].WtyKey, status: response.headers["msgtype"], log: $scope.msg});
},
function(error) {
console.log('Error reading msg: ', error);
}
);
}
}
};
这个问题是它只接受数组中的最后一个元素,因为它是一个异步调用而循环不会等待响应,我尝试使用$q.all()
但是无法弄清楚如何实现这个,有人可以帮忙吗?
答案 0 :(得分:1)
根据我的理解,你的工厂工作正常,就像@RaviMone所说,在for循环中使用异步回调代码,你会惊讶于初学者经常陷入陷阱。此外,我看到$scope.msg
,不知道它来自何处以及它是如何工作的,但由于您的呼叫的异步和并行特性,它可能会显示各种呼叫的错误值,如果它每次呼叫更改,您应该考虑序列化你的电话。
编写$scope.getLogs
的更简洁方法可能是(我减少了jQuery的使用,使用了ES5的东西,如果你必须支持遗留系统,你可以使用this):
$scope.getLogs = function(){
var result = [] // again not sure where the result comes from, so initizing it here, else you can append filtered array to the previous set
$scope.modifiedSN.forEach(function(value) {
if (result.indexOf(value) < 0) result.push(e);
});
$scope.inputs.push({SN:'', Key:'', status:'', log:''});
var promises = result.map(function(val){
return $scope.data[val];
}).filter(function(val){
return val && val.SerialNumber !== ""; // first check if $scope.data[j] exists
}).map(function(val){
return registerPostFactory.getMessage({
IConvRuleFlg: '',
LvEmailId: '',
WKey: val.WtyKey,
SrNum: val.SerialNumber
}).then(function(response){
$scope.msg = response.headers["custommessage"];
val.AutolinkErrorlog = $scope.msg;
$scope.inputs.push({SN: val.SerialNumber, Key: val.WtyKey, status: response.headers["msgtype"], log: $scope.msg});
}).catch(function(e){
console.log('Error reading msg: ', e);
});
});
$q.all(promises)
.then(function(resArray){
console.log('get all logs...');
}).catch(function(e){
console.log('some error: ', e);
});
};
修改:
如果你想按顺序完成它们:
$scope.getLogs = function(){
var result = [] // again not sure where the result comes from, so initizing it here, else you can append filtered array to the previous set
, serialPromise = $q.when(1); // just initializing a promise.
$scope.modifiedSN.forEach(function(value) {
if (result.indexOf(value) < 0) result.push(e);
});
$scope.inputs.push({SN:'', Key:'', status:'', log:''});
result.map(function(val){
return $scope.data[val];
}).filter(function(val){
return val && val.SerialNumber !== ""; // first check if $scope.data[j] exists
}).forEach(function(val){
var datum = {
IConvRuleFlg: '',
LvEmailId: '',
WKey: val.WtyKey,
SrNum: val.SerialNumber
};
serialPromise = serialPromise.then(function(){ // adding a new promise to the chain.
return registerPostFactory.getMessage(datum);
}).then(function(response){
$scope.msg = response.headers["custommessage"];
val.AutolinkErrorlog = $scope.msg;
$scope.inputs.push({SN: val.SerialNumber, Key: val.WtyKey, status: response.headers["msgtype"], log: $scope.msg});
}).catch(function(e){
console.log('Error reading msg: ', e);
});
});
serialPromise.then(function(){
console.log('got all logs...');
}).catch(function(e){
console.log('some error: ', e);
});
};
答案 1 :(得分:0)
这里你必须使用闭包,我修改了你的代码,
(function(data) {
//console.log(data) //You can notice here, you are getting all individual loop objects
var Upddata = {};
Upddata['IConvRuleFlg'] = '';
Upddata['SrNum'] = data.SerialNumber;
Upddata['LvEmailId'] = 'abc@xyz.com';
Upddata['WKey'] = data.WtyKey;
registerPostFactory.getMessage(Upddata, $scope.token, dataurl).then(
function(response) {
$scope.msg = response.headers["custommessage"];
$scope.data[j].AutolinkErrorlog = $scope.msg;
$scope.inputs.push({
SN: data.SerialNumber,
Key: data.WtyKey,
status: response.headers["msgtype"],
log: $scope.msg
});
},
function(error) {
console.log('Error reading msg: ', error);
}
);
})($scope.data[j]);