【问题标题】:AngularJS : Return a promise which is constructed from the result of another promise in angular?AngularJS:返回一个由另一个角度承诺的结果构造的承诺?
【发布时间】:2014-12-23 14:59:06
【问题描述】:

我在服务中定义了以下函数,其中我使用$http 获取一些数据并设置对象的一些字段:

function getComplexObject () {

    var complexObject = {
        'A': null,
        'B': null
    }
    $http.get('someURI').then(function(data) {
        complexObject.A = data;

        //Do some processing and set B 

        return complexObject;
    })
};

所以到目前为止,我已经使用了 $http 服务的承诺,但我不知道如何用 $q 包装函数,以便我最终可以通过以下方式使用它:

//Using my function as a promise
myService.getComplexObject().then(function (data) {
    this.complexObject = data;
})

我搜索了有关 Angular Promise 的教程,但其中大多数只是简单地解释了 Promise 是什么或做一些类似于我已经做过的事情,我猜我想做的事情是可能的,但我找不到正确的语法或正确的教程。

【问题讨论】:

    标签: javascript angularjs promise angular-promise


    【解决方案1】:

    只需将return 放在$http.get(...).then(...) 链的前面,即

    return $http.get(...).then(...);
    

    这将确保getComplexObject 的结果是一个承诺(当它被解析时)包含complexObject 的值。

    这正是.then 的设计目的——它从$http.get() 中获取承诺并返回一个 承诺,该承诺最终将以其自己的返回值而不是原来的返回值来解决。

    FWIW,我将 complexObject 的声明放在 .then 调用中 - 它不需要在外部范围内,它会无意中导致对该变量的关闭。

    注意:另外,请小心在最终回调中使用 this - 它可能不是您认为的那样!

    【讨论】:

    • 谢谢,这很有效,我将尽可能将其标记为已接受的答案,关于这个你是正确的,我将使用 $scope。
    【解决方案2】:

    您可以返回一个承诺并在稍后解决(请参阅:https://docs.angularjs.org/api/ng/service/$q)。

    function getComplexObject () {
    
        var deferred = $q.defer();
        var complexObject = {
            'A': null,
            'B': null
        }
        $http.get('someURI').then(function(data) {
            complexObject.A = data;
    
            //Do some processing and set B 
            deferred.resolve(complexObject);
        });
        return deferred.promise;
    };
    

    【讨论】:

    • 不,这绝对没有必要.then() 已经为您做到了!这是一个承诺反模式。它实际上也破坏了正确的错误处理。见github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns
    • 考虑.catch 的情况——如果$http.get() 调用失败,此代码将完全无法通知调用者,因为它不允许deferred.reject() 调用。结果是这段代码是有害的。
    • “//做一些处理并设置B”怎么样?我想这个评论是有原因的。当然,如果出现错误,必须拒绝承诺。
    • 就承诺处理而言,“set B”部分应该是无关紧要的。这个版本的问题是必须显式添加错误处理,而根据我的回答只需添加return 允许错误自动通过承诺链传播,而无需额外的代码。
    猜你喜欢
    • 2015-11-27
    • 1970-01-01
    • 1970-01-01
    • 2015-12-16
    • 2015-06-05
    • 1970-01-01
    • 2017-09-10
    • 2017-05-16
    • 2015-10-27
    相关资源
    最近更新 更多