簡體   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