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

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

问题描述

列表中的每个电子邮件都将发送到服务器,并且响应从服务器获取,如果它是有效的电子邮件。

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

在环路中发送电子邮件到服务器的代码是:

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

但问题是调用是异步的,所以说i = 0 ,当i为0时,控件不会进入函数内部。因此,当它进入i的函数值时,可以是任何东西,大多数是大于数组的长度,因此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 ?

推荐答案

使用promises。 Angular可以在没有任何特殊干预的情况下使用promise,就像为一个作用域变量赋值一样,参见plnkr。 Promises是使异步编程如同步编程一样工作的基础(虽然我们在浏览器中没有javascript生成器),并且被Angular团队鼓励,因为它是高度可测试和可维护的

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

});

注意: $ timeout 异步任务,如数据库调用等。您可以将整个电子邮件数组传递给验证服务,然后返回数组,而不是创建promise的中间数组。使用angular,您可以为promise分配范围变量,并且您可以在 ng-repeat 上使用它,而不对代码进行任何更改

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天全站免登陆