2015-04-01 288 views
0

我對Angular很陌生,但我試圖找出一些東西。回覆承諾的承諾

我有它返回一個承諾的方法:

preloaderServiceObject.Load = function(referencePaths){ 
    var deferred = $q.defer(); 

    $(referencePaths).each(function(index, referencePath) { 
     var preloadedElement = document.createElement('img'); 
     { 
      preloadedElement.onload = deferred.resolve; 
      preloadedElement.src = referencePath; 
     } 
    }); 

    return deferred.promise; 
} 

這是所有工作的罰款,並不會造成問題。 不過,我確實有它應該會返回一個承諾的承諾完成調用之內,像這樣一種方法:

OfficeUIRibbonControlServiceObject.Initialize = function(configurationFile) { 
    $http.get(configurationFile) 
     .then(function (response) { 
      $rootScope.Tabs = response.data.Tabs; 
      $rootScope.ContextualGroups = response.data.ContextualGroups; 

      var images = JSPath.apply('.Groups.Areas.Actions.Resource', $rootScope.Tabs); 
      images.concat(JSPath.apply('.Tabs.Groups.Areas.Actions.Resource', $rootScope.ContextualGroups)); 

      PreloaderService.Load(images); 
     }); 
} 

最後一行PreloaderService.Load(images);不會返回如在這篇文章的第一個函數定義的一個承諾。

但是,現在我想調用方法'OfficeUIRibbonControlServiceObject.Initialize',但我該如何更改此方法,以便可以等到PreloaderService的加載完成?

只是改變了方法返回的承諾將無法正常工作,因爲返回的對象是不確定的(因爲我在$ HTTP的then方法是。

親切的問候,

編輯:如所建議的通過魯比,使用一個承諾:

初始化函數:

OfficeUIRibbonControlServiceObject.Initialize = function(configurationFile) { 
    $http.get(configurationFile) 
     .then(function (response) { 
      $rootScope.Tabs = response.data.Tabs; 
      $rootScope.ContextualGroups = response.data.ContextualGroups; 

      var images = JSPath.apply('.Groups.Areas.Actions.Resource', $rootScope.Tabs); 
      images.concat(JSPath.apply('.Tabs.Groups.Areas.Actions.Resource', $rootScope.ContextualGroups)); 

      var deferred = $q.defer(); 
      PreloaderService.Load(images).then(function() { 
       deferred.resolve(); 
      }); 

      return deferred; 
     }); 
} 

的InitializeService方法:

function InitializeService(serviceInstance, configurationFile) { 
    serviceInstance.Initialize(configurationFile).then(function() { 
     console.log('This method has been called.'); 
    }); 
} 

這樣做的結果是,我得到:Error: serviceInstance.Initialize(...) is undefined

+0

您需要在Initialize函數的作用域中創建延遲 – Rouby 2015-04-01 07:00:17

+0

請參閱[「應該在其標題中包含」標籤「嗎?」](http: //meta.stackexchange.com/questions/19190/should-questions-include-tags-in-their-titles),其中共識是「不,他們不應該」! – 2015-04-01 07:02:28

+0

@Rouby這似乎工作。將deferred的定義作爲第一行,將其解析爲Load方法的then()函數,然後將其作爲最後一條語句返回。 – Complexity 2015-04-01 07:07:09

回答

0

創建一個新的.Initialize推遲該得到解決,當第二.Load完成後,你就可以回到這個延遲是正常。

E.g.

PreloaderService.Load(images).then(function(){ newDeferred.resolve(); }, function(){ newDeferred.reject(); }); 
+0

感謝您的解決方案,但我對AngularJS頗爲陌生。你介意多解釋一下嗎? – Complexity 2015-04-01 06:49:50

+0

我認爲這與Angular沒什麼特別的關係,但更多的是承諾。你需要進一步解釋什麼? – Rouby 2015-04-01 06:51:56

+0

如何與延期工作。我對它很陌生,條款並沒有多說我。 – Complexity 2015-04-01 06:52:54

0

更好的回報承諾:

OfficeUIRibbonControlServiceObject.Initialize = function(configurationFile) { 
return $http.get(configurationFile) 
    .then(function (response) { 
     $rootScope.Tabs = response.data.Tabs; 
     $rootScope.ContextualGroups = response.data.ContextualGroups; 

     var images = JSPath.apply('.Groups.Areas.Actions.Resource', $rootScope.Tabs); 
     images.concat(JSPath.apply('.Tabs.Groups.Areas.Actions.Resource', $rootScope.ContextualGroups)); 

     return PreloaderService.Load(images); 
    }); 

}

當你現在所說的OfficeUIRibbonControlServiceObject.Initialize功能結果PreloaderService.Load將被退回。

例如:

OfficeUIRibbonControlServiceObject.Initialize(// myConfiguration //).then (
    function success (response) { 
     console.log("promise success", response) 
    }, 
    function fail (error) { 
     console.log("promise fail", error) // the result from PreloaderService.Load 
    } 
); 

一般:你可以在.then函數返回值或承諾。當你返回一個承諾。該承諾的解析值將在解決承諾後返回

+0

我相信''http.get'之前應該有'return'。 – Chandermani 2015-04-01 06:58:31

+0

當我執行此操作時,以下調用'serviceInstance.Initialize(configurationFile)'將導致未識別的對象。 – Complexity 2015-04-01 07:00:11

+0

感謝Chandermani,函數應該返回http.get的承諾。我編輯答案 – 2015-04-01 07:23:24