Retourner immédiatement une promesse résolue en utilisant AngularJS

j'essaie de comprendre les promesses en JavaScript (en particulier AngularJS).

j'ai une fonction dans un service, appelons-la fooService , qui vérifie si nous avons chargé quelques données. Si c'est le cas, je veux juste qu'il revienne, Et si nous ne l'avons pas fait, nous devons charger les données et retourner une promesse:

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

j'ai une autre fonction qui appelle ensuite la fonction update de fooService comme ceci:

fooService.update(data_loaded).then(function() {
    // Do something here when update is finished
})

mon problème ici est que si nous n'avons pas besoin de charger les données dans la fonction update , une promesse n'est pas retournée, donc le .then() n'est pas appelé dans mon autre fonction. Quelle devrait être l'approche ici-fondamentalement je veux retourner une promesse résolue immédiatement de la fonction update() si nous n'avons pas besoin d'obtenir des données de l'appel Restangular?

23
demandé sur Peter Mortensen 2014-07-17 07:29:02

5 réponses

Les accepté de réponse est trop compliqué, et les abus de la "151930920 différée" anti-modèle . Voici une approche plus simple:

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 
    });
};

ou encore:

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;
};
26
répondu Benjamin Gruenbaum 2017-05-23 12:26:33

comme votre promesse utilise la même syntaxe que la promesse native de JavaScript, vous pouvez utiliser et retourner une promesse déjà résolue de JavaScript: promesse.resolve()

return(Promise.resolve("MyReturnValue"));
39
répondu Elo 2015-07-09 08:56:00

Angularjs's $q le service vous aidera ici. C'est un peu comme Kris Kowal "Q bibliothèque promise.

lorsque vous avez une méthode async qui peut retourner une promesse ou une valeur $Q. quand méthode. Il va prendre ce que jamais est passé, que ce soit une promesse ou une valeur et créer une promesse que sera résolu / rejeté en fonction de la promesse passée, ou résolu si une valeur est passée.

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

et ensuite dans votre fonction de mise à jour retourner les données au lieu de simplement retourner

if (data_loaded) return data_loaded;
6
répondu Patrick Evans 2014-07-17 03:48:10

similaire à réponse D'Elo , vous pouvez retourner une promesse déjà résolue en utilisant la syntaxe async/attente:

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();
}
0
répondu Zanon 2018-07-23 11:27:45

vous pouvez utiliser le $q.defer() comme ceci:

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

Espérons que cette aide.

-2
répondu runTarm 2014-07-17 03:49:52