AngularJS:等待异步调用

use*_*960 11 javascript synchronization angularjs

我无法理解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;
                  });
              }
           }
       }
   }
});
Run Code Online (Sandbox Code Playgroud)

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

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

var packings = packingProvider.getPackings();

console.log(packings); // undefined
Run Code Online (Sandbox Code Playgroud)

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

Kon*_*n K 7

尝试

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
                  });
              }
           }
       }
   }
});
Run Code Online (Sandbox Code Playgroud)

然后

packingProvider.getPackings().then(function(packings){
    console.log(packings);
});
Run Code Online (Sandbox Code Playgroud)

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

$scope.packings = packingProvider.getPackings();
Run Code Online (Sandbox Code Playgroud)

UPDATE

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


drh*_*yes 7

then您认为它的方法中的返回值不会返回; 它回来了.

在语句中var packings = packingProvider.getPackings();,返回值是未定义的,因为从中返回的promise $http是异步的.这意味着调用$http.post发生,没有完成,然后你的函数返回.在没有返回任何内容的JS函数中返回undefined.该post呼叫后完成,并执行return packings;它获取回到行不通的.

getPackings方法应该可以$http.post直接从承诺中返回.这样,任何想要使用此方法的代码都可以then直接调用promise并按照需要的方式设置值.在控制器中,您可以直接将该承诺分配给$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');
    }
  };
});
Run Code Online (Sandbox Code Playgroud)

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