如何使用在角循环异步调用? [英] How to use asynchronous calls in a loop in angular?

查看:112
本文介绍了如何使用在角循环异步调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个列表中的每个电子邮件将被发送到服务器,并响应于从服务器获得,如果它是一个有效的电子邮件。

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 :

joe@gmail.com - valid
abc@fjkdsl.com - invalid
xyz@yahoo.com - valid
test@nknk.com - invalid

在code发送邮件服务器在一个循环是这样的:

The code to send the emails to server in a loop is like :

for(var i=0; i < isEmailValidList.length; i++) {
  var isEmailValid = User.validateEmail({email : isEmailValidList[i].email}, function(){
      isEmailValidList[i].isValid = isEmailValid.value;
  });
}

但问题是,调用是异步的,所以说我= 0,控制不会在函数内部去的时候我是0,所以当它的函数值往里走的,我可以是任何东西,主要是它比阵列的长度,所以isEmailValidList [i]为未定义。如果调用是同步的,然后它会等待响应,我不会一直在增加,但这种情况并非如此。

But the problem is that the calls are asynchronous, so for say i=0, the control will not go inside the function when i is 0. So when it does go inside the function value of i can be anything, mostly it is greater than length of array, so isEmailValidList[i] is undefined. If the call were synchronous then it would have waited for response and i would not have been incremented, but this is not the case.

那么,如何才能获得其相应的电子邮件正确的isValid反应?

So, how do I get the correct isValid response for its corresponding email ?

推荐答案

使用的承诺。角可以与承诺的工作没有任何特殊的干预,就像一个范围的变量赋值,请参阅plnkr。承诺是基地驯服异步编程一样同步编程工作(虽然我们没有在浏览器中的JavaScript发电机),由角团队鼓励,因为它的高度可测试和维护

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=$p$ PVIEW

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

});

注: $超时是模拟一个异步任务,就像一个数据库调用等,您可以传递整个电子邮件阵列到验证服务,然后返回数组,而不是创建承诺的中间阵列。具有角,你可以一个范围的变量赋值给一个承诺,你可以使用它在 NG-重复没有任何改变code

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

这篇关于如何使用在角循环异步调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆