立即使用AngularJS返回已解决的承诺

时间:2014-07-17 03:29:02

标签: javascript angularjs promise restangular angular-promise

我试图了解JavaScript中的承诺(特别是AngularJS)。

我在服务中有一个函数,我们称之为fooService,它检查我们是否加载了一些数据。如果有,我只想让它返回,如果我们没有,我们需要加载数据并返回一个承诺:

this.update = function(data_loaded) {
    if (data_loaded) return;  // We've loaded the data, no need to update

    var promise = Restangular.all('someBase').customGet('foo/bar').then(function(data) {
        // Do something with the data here
    }

    return promise;
}

我有另一个函数,然后调用update的{​​{1}}函数,如下所示:

fooService

我的问题是,如果我们不需要在fooService.update(data_loaded).then(function() { // Do something here when update is finished }) 函数中加载数据,则不会返回承诺,因此在我的其他函数中不会调用update。这里的方法应该是什么 - 基本上我想立即从.then()函数返回一个已解决的承诺,如果我们不需要从Restangular调用中获取数据?

5 个答案:

答案 0 :(得分:43)

由于您的承诺使用与JavaScript本机相同的语法,您可以使用并返回已经解析的JavaScript承诺:Promise.resolve()

return(Promise.resolve("MyReturnValue"));

答案 1 :(得分:27)

当前接受的答案过于复杂,并滥用deferred anti pattern。这是一个更简单的方法:

this.update = function(data_loaded) {
    if (data_loaded) return $q.when(data);  // We've loaded the data, no need to update

    return Restangular.all('someBase').customGet('foo/bar')
                             .then(function(data) {
        // Do something with the data here 
    });
};

或者,甚至更进一步:

this._updatep = null;
this.update = function(data_loaded) { // cached
    this._updatep = this._updatep || Restangular.all('someBase') // process in
                                                .customGet('foo/bar'); //.then(..
    return this._updatep;
};

答案 2 :(得分:6)

AngularJS的$q服务将在这里为您提供帮助。它很像Kris Kowal's Q承诺库。

如果您有可能返回promise或值的异步方法,请使用$q.when方法。它将传递给它,无论是承诺还是价值,并根据传递的承诺创建将被解决/拒绝的承诺,或者在传递值时解决。

$q.when( fooService.update(data_loaded) ).then(function(data){
   //data will either be the data returned or the data
   //passed through from the promise
})

然后在你的更新函数中返回数据而不是只返回

if (data_loaded) return data_loaded;

答案 3 :(得分:0)

类似于Elo's answer,您可以使用async / await语法返回已解决的Promise:

this.update = async (data_loaded) => {

    if (data_loaded) 
        return await null;  // Instead of null, you could also return something else
                            // like a string "Resolved" or an object { status: 200 }
    else 
        return await OtherPromise();
}

答案 4 :(得分:-2)

您可以像这样使用$q.defer()

this.update = function (data_loaded) {
    var deferred = $q.defer();

    if (data_loaded) {
        deferred.resolve(null); // put something that your callback will know the data is loaded or just put your loaded data here.
    } else {
        Restangular.all('someBase').customGet('foo/bar').then(function(data) {
            // Do something here when update is finished
            deferred.resolve(data);
        }
    }

    return deferred.promise;
};

希望这有帮助。