Javascript AngularJS:在循环中调用工厂方法

Javascript AngularJS:在循环中调用工厂方法,javascript,angularjs,promise,factory,Javascript,Angularjs,Promise,Factory,我有一个工厂方法,如下所示: angular.module('GridSamplesApp') .factory('registerPostFactory', function($resource, $q, WebRequest) { var getMessage = function(Upddata, token, dataurl) { var deferred = $q.defer(); var settings = {

我有一个工厂方法,如下所示:

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

};
$scope.getLogs=function()
{
$.each($scope.modifiedSN,函数(即){
如果($.inArray(e,result)=-1)result.push(e);
});
$scope.inputs.push({SN:'',键:'',状态:'',日志:'});

对于(var i=0;i这里您必须使用闭包,我已经修改了您的代码

(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]);

据我所知,您的工厂工作正常,正如@RaviMone所说,它是在for循环中使用异步回调代码的,您会惊讶于初学者经常落入这种陷阱。此外,我看到一个
$scope.msg
,不确定它来自何处以及如何工作,但由于您调用的异步和并行性质,它可能是di为各种调用显示错误的值,如果每次调用都会更改,则应考虑序列化调用

编写
$scope.getLogs
的更简洁的方法可能是(我已经减少了jQuery的使用,使用了ES5的东西,如果您必须支持遗留系统,您可以使用):

$scope.getLogs=function(){
var result=[]//同样不确定结果来自何处,因此在此处初始化它,否则可以将过滤后的数组附加到上一个集合中
$scope.modifiedSN.forEach(函数(值){
if(result.indexOf(value)<0)result.push(e);
});
$scope.inputs.push({SN:'',键:'',状态:'',日志:'});
var=result.map(函数(val){
返回$scope.data[val];
}).过滤器(功能(val){
返回val&&val.SerialNumber!==“”;//首先检查$scope.data[j]是否存在
}).map(函数(val){
返回registerPostFactory.getMessage({
IConRuleFLG:“”,
LvEmailId:“”,
WKey:val.WtyKey,
SrNum:val.SerialNumber
}).然后(功能(响应){
$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(函数(e){
log('读取消息时出错',e);
});
});
$q.all(承诺)
.然后(功能(重新排列){
log('获取所有日志…');
}).catch(函数(e){
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);
    });
};
$scope.getLogs=function(){
var result=[]//同样不确定结果来自何处,因此在此处初始化它,否则可以将过滤后的数组附加到上一个集合中
,serialPromise=$q.when(1);//只是初始化一个承诺。
$scope.modifiedSN.forEach(函数(值){
if(result.indexOf(value)<0)result.push(e);
});
$scope.inputs.push({SN:'',键:'',状态:'',日志:'});
结果映射(函数(val){
返回$scope.data[val];
}).过滤器(功能(val){
返回val&&val.SerialNumber!==“”;//首先检查$scope.data[j]是否存在
}).forEach(函数(val){
var数据={
IConRuleFLG:“”,
LvEmailId:“”,
WKey:val.WtyKey,
SrNum:val.SerialNumber
};
serialPromise=serialPromise.then(函数(){//向链中添加新承诺。
返回registerPostFactory.getMessage(数据);
}).然后(功能(响应){
$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(函数(e){
log('读取消息时出错',e);
});
});
serialPromise.then(函数(){
log('获取所有日志…');
}).catch(函数(e){
log('some error:',e);
});
};

Hi-Neha,您必须使用javascript的闭包来调用API的内部闭包;可能重复Hi,这仍然只考虑循环中的最后一条记录。它不会等待响应返回,我想将下一个循环挂起,直到我获得上一项的响应。Hi,我得到的重新排列未定义,我不确定如何更正。您能帮我吗?
重新排列
未定义,总之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);
    });
};