繁体   English   中英

AngularJS:等待异步调用

[英]AngularJS: Waiting for an asynchronous call

我无法理解AngularJS的承诺概念。

我有一个提供者:

var packingProvider = angular.module('packingProvider',[]);

packingProvider.provider('packingProvider',function(){
    return{
       $get: function($http){
           return{
              getPackings: function(){
                  $http.post('../sys/core/fetchPacking.php').then(function(promise){
                      var packings = promise.data;
                      return packings;
                  });
              }
           }
       }
   }
});

如您所见,这提供了一个方法getPackings() ,它将返回一个对象

现在,如果我在主应用程序中使用它来接收数据,则调用将是异步的,从而导致我必须“等待”数据的问题:

var packings = packingProvider.getPackings();

console.log(packings); // undefined

如果不将进程重构到我的主控制器中,我该怎么做?

尝试

var packingProvider = angular.module('packingProvider',[]);

packingProvider.provider('packingProvider',function(){
    return{
       $get: function($http){
           return{
              getPackings: function(){
                  return $http.post('../sys/core/fetchPacking.php').then(function(response){
                      return response.data; // packings
                  });
              }
           }
       }
   }
});

然后

packingProvider.getPackings().then(function(packings){
    console.log(packings);
});

主要思想:您需要从getPackings函数返回promise对象。 不确定你是否可以同步调用它,但这样做几乎绝对不是一个好主意。 此外,如果要在控制器上创建“填充”模型对象并用于双向绑定,则可以安全地分配promise对象,Angular将在数据通过后立即解析:

$scope.packings = packingProvider.getPackings();

UPDATE

从1.2.0-rc.3开始,承诺解包已被弃用( https://github.com/angular/angular.js/blob/master/CHANGELOG.md#120-rc3-ferocious-twitch-2013-10-14 ),所以上面的代码行不再导致双向绑定。

当你认为它时,你的then方法中的返回值不会返回; 它回来了。

在声明中var packings = packingProvider.getPackings(); 返回值是未定义的,因为从$http返回的promise是异步的。 这意味着对$http.post的调用发生, 没有完成 ,然后你的函数返回。 在没有返回任何内容的JS函数中返回undefined。 post调用稍后完成并执行return packings; 它无处可归。

getPackings方法应该可以直接从$http.post返回promise。 这样,想要使用这种方法可以调用任何代码, then直接在承诺和所设置的值,它需要的方式。 在控制器中,您可以将该承诺直接分配给$scope并在视图中使用它。 这是一个很好的帖子,解释了这个特殊的功能: http//markdalgleish.com/2013/06/using-promises-in-angularjs-views/

顺便说一句,看起来你在那里有一个冗长的服务声明; 有什么理由不把它缩短到这样的东西?

var module = angular.module('packing', []);

module.service('packing', function($http) {
  return {
    getPackings: function() {
      return $http.post('../sys/core/fetchPacking.php');
    }
  };
});

我对AngularJS比较陌生,但我没有看到所有输入都有任何好处。 (=

有大量资源可以向您展示如何使用jQuery的Deferreds / Promises。 尝试搜索那些,这可能会帮助您克服这个障碍。 Afaik,AngularJS承诺与jQuery承诺相同。

一个jQuery承诺使用这样的东西:

var getPackings = function() { return $.get('../sys/core/fetchPacking.php'); };
var packings;
$.when(getPackings()).then(function(data){ packings = data; console.log(packings) });

请记住,jQuery ajax调用具有.done,.success等函数,它们将替换泛型Deferreds的.when()。then()函数。

在上面的jQuery方法中,您可以看到我们必须设置数据并将其输出到.then()函数中,因为您无法保证异步过程在其他任何地方完成。 因此,理想情况下,您可以调用.then()函数中继续处理的任何函数,如下所示:

$.when(myAsyncFunc()).then(myAppCanContinue(dataReturnedByAsyncFunc));

Angular将遵循相同的逻辑。 如果您了解上述内容,则应该更容易理解如何在Angular中实现此目的。 另外,请查看这篇提供简单示例的文章: http//markdalgleish.com/2013/06/using-promises-in-angularjs-views/

为了让您的代码正常工作,您需要执行以下操作:

packingProvider.provider('packingProvider',function(){
    return{
       $get: function($http){
           return{
              getPackings: function(){
                  return $http.post('../sys/core/fetchPacking.php');
              }
           }
       }
   }
});
var packings = packingProvider.getPackings();

packings.then(function(data) { console.log(data)});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM