web-dev-qa-db-fra.com

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é des données. Si tel est le cas, je souhaite simplement qu'il soit renvoyé, et si ce n'est pas le cas, nous devons charger les données et renvoyer 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 renvoyée et la .then() n’est donc pas appelée dans mon autre fonction. Quelle devrait être l'approche ici? En gros, je souhaite renvoyer immédiatement une promesse résolue de la fonction update() si nous n'avons pas besoin d'obtenir des données de l'appel Restangular.

24
samturner

La réponse acceptée actuellement est excessivement compliquée et abuse du anti pattern différé . 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 plus loin:

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
Benjamin Gruenbaum

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

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

Le service _ { $ q [} } d'AngularJS vous aidera ici. Cela ressemble beaucoup à la bibliothèque de promesses de { Kris Kowal .

Si vous utilisez une méthode asynchrone pouvant renvoyer une promesse ou une valeur, utilisez la méthode $ q.when . Cela prendra ce qui lui est jamais transmis, que ce soit une promesse ou une valeur, pour créer une promesse qui sera résolue/rejetée en fonction de la promesse passée, ou résolue 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
})

puis dans votre fonction de mise à jour renvoyer les données au lieu de simplement revenir

if (data_loaded) return data_loaded;
6
Patrick Evans

Semblable à La réponse Elo , vous pouvez retourner une promesse déjà résolue en utilisant la syntaxe async/wait:

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
Zanon