Javascript AngularJS:正在等待异步调用

Javascript AngularJS:正在等待异步调用,javascript,angularjs,synchronization,Javascript,Angularjs,Synchronization,我无法理解AngularJS的承诺概念 我有一个提供者: var packingProvider = angular.module('packingProvider',[]); packingProvider.provider('packingProvider',function(){ return{ $get: function($http){ return{ getPackings: function(){

我无法理解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
                  });
              }
           }
       }
   }
});
然后

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

$scope.packings = packingProvider.getPackings();
更新


从1.2.0-rc.3开始,promise unwrapping已被弃用(),因此上面的代码行将不再导致双向绑定。

您的
方法中的返回值不会在您认为是时返回;一会儿就回来

在语句
var packings=packingProvider.getPackings()中
返回值未定义,因为从
$http
返回的承诺是异步的。这意味着对
$http.post
的调用发生,但未完成,然后函数返回。在JS中,不返回任何内容的函数返回未定义的。
post
调用稍后完成并执行
返回打包返回到任何地方

getPackings
方法可能应该直接从
$http.post
返回承诺。这样,任何想要使用此方法的代码都可以直接调用promise上的
,然后
,并按照需要的方式设置值。在控制器中,您可以将该承诺直接分配给
$scope
,并在视图中使用它。下面是一篇很好的帖子,解释了这一特殊功能:

顺便说一句,这里似乎有一个冗长的服务声明;有没有理由不把它缩短成这样

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

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

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

有大量可用资源向您展示如何在jQuery中使用延迟/承诺。尝试搜索这些资源,这可能会帮助您克服这一障碍。好吧,AngularJS承诺与jQuery承诺相同

jQuery承诺的用法如下:

var getPackings = function() { return $.get('../sys/core/fetchPacking.php'); };
var packings;
$.when(getPackings()).then(function(data){ packings = data; console.log(packings) });
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)});
请记住,jQuery ajax调用具有.done、.success等函数,这些函数将替换通用的延迟“.when().then()函数

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

$.when(myAsyncFunc()).then(myAppCanContinue(dataReturnedByAsyncFunc));
Angular将遵循相同的逻辑。如果您理解上述内容,那么应该更容易理解如何在Angular中实现这一点。此外,请参阅本文,其中给出了一些简单的示例:

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

var getPackings = function() { return $.get('../sys/core/fetchPacking.php'); };
var packings;
$.when(getPackings()).then(function(data){ packings = data; console.log(packings) });
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)});

那么
getPackings
也返回一个
promise
?忘了提到另一个关键点:您可以随意链接“then”s:从“then”返回的值将传递给后续的“then”作为一个论证,谢谢,真的帮了我很大的忙。到目前为止,我认为选择一个提供者而不是一个简单的服务总是一个好主意,因为它具有更高的可配置性。在每次默认情况下选择提供者时有什么缺点吗?大多数情况下,你可能不需要很多代码。真的,这取决于什么类型的c您想要的配置。您正在设置值吗?为什么不将
常量
注入到您的服务中呢?如果您正在编写一个要在库中使用的服务,我可以看到使用
提供者
调用,这样库的消费者就不必知道您正在注入的这些神奇值,而是其他的明智地说,直接的
服务
会更简单。