How to use asynchronous calls in a loop in angular?

后端 未结 2 1241
眼角桃花
眼角桃花 2020-12-21 16:53

Each email in a list is to be sent to server and response to be be got from server that if it is a valid email.

So after all emails are checked the array should have

相关标签:
2条回答
  • 2020-12-21 17:16

    Use promises. Angular can work with promises without any "special intervention", just like assigning a value to a scope variable, see the plnkr. Promises are the "base" to tame asynchronous programming to work like synchronous programming (while we don't have javascript generators in browsers) and is encouraged by Angular team because it's highly testable and maintainable

    http://plnkr.co/edit/8BBS2a1kC24BHBWRYp9W?p=preview

    // trying to emulate your service here
    
    var app = angular.module('app', []);
    
    app.factory('User', function($q, $timeout){
      User = {};
    
      User.validateEmail = function(email){
        var d = $q.defer();
    
        $timeout(function(){
          if (/(yahoo|gmail)/.test(email.email)){
            d.resolve(email); // return the original object, so you can access it's other properties, you could also modify the "email" object to have isValid = true, then resolve it
          } else {
            d.resolve(); // resolve it with an empty result
          }
        }, 1000, false);
    
        return d.promise;
      };
    
      return User;
      });
    
    app.controller('MainCtrl', function(User, $q){
      this.emails = [
        {email: 'joe@gmail.com', name: 'Joe'},
        {email: 'abc@fjkdsl.com', name: 'Abc'},
        {email: 'xyz@yahoo.com', name: 'XYZ'}, 
        {email: 'test@nknk.com', name: 'test'}
      ];
    
      this.isEmailValidList = [];
      var promises = [];
    
      for(var i=0; i < this.emails.length; i++) {
        promises.push(
          User.validateEmail(this.emails[i]) 
        );
      }
    
      $q.all(promises).then(function(emails){ 
        this.isEmailValidList = emails.filter(function(e){ return e; });
      }.bind(this));
    
    });
    

    Notes: The $timeout is to emulate an asynchronous task, like a database call, etc. You could pass the entire emails array to the validation service then return the array, instead of creating an intermediate array of promises. With angular, you may assign a scope variable to a promise, and you can use it on ng-repeat without any changes to the code

    0 讨论(0)
  • 2020-12-21 17:24

    You can use closure function:

    for (var i=0; i < isEmailValidList.length; i++) {
      var isEmailValid = User.validateEmail({
         email : isEmailValidList[i].email
      }, (function(i) {
         return function() {
             isEmailValidList[i].isValid = isEmailValid.value;
         };
      })(i));
    }
    
    0 讨论(0)
提交回复
热议问题