【问题标题】:Return a promise of a promise返回一个承诺的承诺
【发布时间】:2015-06-05 17:28:27
【问题描述】:

我对 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;
}

这一切正常,不会导致问题。 但是,我确实有另一种方法应该在 promise 的完成调用中返回一个 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 方法中。

亲切的问候,

编辑:按照 Rouby 的建议,使用承诺:

初始化函数:

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

【问题讨论】:

  • 需要在Initialize函数范围内创建deferred
  • 请参阅"Should questions include “tags” in their titles?",其中的共识是“不,他们不应该”!
  • @Rouby 这似乎有效。将deferred的定义放在第一行,在Load方法的then()函数中解析,然后作为最后一个语句返回。

标签: javascript jquery angularjs


【解决方案1】:

最好兑现承诺:

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 函数中返回值或承诺。当你回报一个承诺。该承诺的解析值将在该承诺解决后返回

【讨论】:

  • 我相信$http.get之前也应该有一个return
  • 当我执行这个时,下面的调用serviceInstance.Initialize(configurationFile) 将导致一个无法识别的对象。
  • 感谢 Chandermani,该函数应该返回 http.get 承诺。我编辑答案
【解决方案2】:

.Initialize 中创建一个新的 deferred,它会在第二个 .Load 完成时得到解决,然后您可以正常返回这个 deferred。

例如

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

【讨论】:

  • 感谢您的解决方案,但我对 AngularJS 还是很陌生。你介意再解释一下吗?
  • 我认为这与 Angular 没有什么特别的关系,但更多的是与承诺有关。您究竟需要进一步解释什么?
  • 如何与 deferred 完全一致。我是新手,条款并没有说明太多。
  • 我在上面提到了我在问题的编辑部分所做的事情。你可以看看,因为它仍然无法正常工作。提前致谢。
  • 我已经接受了您的回答,因为它似乎有效。感谢您的建议。
猜你喜欢
  • 2015-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-18
相关资源
最近更新 更多