wake-up-neo.net

Bringen Sie ein gelöstes Versprechen umgehend mit AngularJS zurück

Ich versuche, meine Versprechungen in JavaScript (insbesondere AngularJS) zu verbessern.

Ich habe eine Funktion in einem Dienst, nennen wir es fooService, die prüft, ob wir Daten geladen haben. Wenn ja, möchte ich nur, dass es zurückkehrt, und wenn nicht, müssen wir die Daten laden und ein Versprechen zurückgeben:

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

Ich habe eine andere Funktion, die dann die update-Funktion von fooService wie folgt aufruft:

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

Mein Problem hier ist, dass, wenn wir die Daten nicht in die update-Funktion laden müssen, kein Versprechen zurückgegeben wird, sodass die .then() in meiner anderen Funktion nicht aufgerufen wird. Was sollte der Ansatz hier sein - im Grunde möchte ich ein gelöstes Versprechen sofort von der Funktion update() zurückgeben, wenn wir keine Daten vom Restangular-Aufruf abrufen müssen?

24
samturner

Die derzeit akzeptierte Antwort ist zu kompliziert und missbraucht das verzögerte Antimuster . Hier ist ein einfacherer Ansatz:

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

Oder noch weiter:

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

Da Ihr Versprechen dieselbe Syntax wie das native JavaScript verwendet, können Sie ein bereits gelöstes JavaScript-Versprechen verwenden und zurückgeben: Promise.resolve ()

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

Der AngularJS $ q - Service wird Ihnen hier helfen. Es ist sehr ähnlich wie Kris Kowals Q Promise-Bibliothek.

Wenn Sie über eine asynchrone Methode verfügen, die möglicherweise ein Versprechen oder einen Wert zurückgibt, verwenden Sie die Methode $ q.when . Es wird das, was auch immer übergeben wird, sein, sei es ein Versprechen oder ein Wert, und es wird ein Versprechen geschaffen, das basierend auf dem übergebenen Versprechen gelöst oder abgelehnt wird, oder bei einem Wertübergang gelöst.

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

und dann in Ihrer Aktualisierungsfunktion die Daten zurückgeben, anstatt nur zurückzukehren

if (data_loaded) return data_loaded;
6
Patrick Evans

Ähnlich wie Elo's answer können Sie ein bereits gelöstes Versprechen mit der async/await-Syntax zurückgeben:

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