Ich habe einen i18n-Dienst in meiner Anwendung, der den folgenden Code enthält:
var i18nService = function() {
this.ensureLocaleIsLoaded = function() {
if( !this.existingPromise ) {
this.existingPromise = $q.defer();
var deferred = this.existingPromise;
var userLanguage = $( "body" ).data( "language" );
this.userLanguage = userLanguage;
console.log( "Loading locale '" + userLanguage + "' from server..." );
$http( { method:"get", url:"/i18n/" + userLanguage, cache:true } ).success( function( translations ) {
$rootScope.i18n = translations;
deferred.resolve( $rootScope.i18n );
} );
}
if( $rootScope.i18n ) {
this.existingPromise.resolve( $rootScope.i18n );
}
return this.existingPromise.promise;
};
Die Idee ist, dass der Benutzer anruft ensureLocaleIsLoaded
und wartet, bis das Versprechen gelöst ist. Da der Zweck der Funktion jedoch darin besteht, nur sicherzustellen, dass das Gebietsschema geladen ist, ist es für den Benutzer vollkommen in Ordnung, es mehrmals aufzurufen.
Ich speichere derzeit nur ein einzelnes Versprechen und löse es, wenn der Benutzer die Funktion erneut aufruft, nachdem das Gebietsschema erfolgreich vom Server abgerufen wurde.
Soweit ich das beurteilen kann, funktioniert dies wie beabsichtigt, aber ich frage mich, ob dies ein angemessener Ansatz ist.
javascript
angularjs
Der Hochstapler
quelle
quelle
Antworten:
Soweit ich derzeit Versprechen verstehe, sollte dies zu 100% in Ordnung sein. Das einzige, was zu verstehen ist, ist, dass, sobald es aufgelöst (oder abgelehnt) ist, es für ein zurückgestelltes Objekt ist - es getan wird.
Wenn Sie
then(...)
das Versprechen erneut einholen sollten, sollten Sie sofort das (erste) gelöste / abgelehnte Ergebnis erhalten.Zusätzliche Anrufe an
resolve()
werden keine Wirkung haben (sollten nicht?). Ich bin mir nicht sicher, was passiert, wenn Sie versuchen,reject
ein zuvor verschobenes Objekt zu verwendenresolved
(ich vermute nichts).quelle
Ich war vor einiger Zeit mit dem gleichen Problem konfrontiert, tatsächlich kann ein Versprechen nur einmal gelöst werden, ein weiterer Versuch wird nichts bewirken (kein Fehler, keine Warnung, kein
then
Aufruf).Ich habe beschlossen, es so zu umgehen:
Übergeben Sie einfach Ihre Funktion als Rückruf und rufen Sie sie so oft auf, wie Sie möchten! Hoffe das macht Sinn.
quelle
getUsers
und es dann.then()
so oft aufrufen , wie Sie möchten. Es ist nicht erforderlich, einen Rückruf weiterzuleiten. Meiner Meinung nach ist einer der Vorteile von Versprechungen, dass Sie den Rückruf nicht im Voraus angeben müssen..then
Anweisungen zu haben. Ich denke, die einzige Möglichkeit, Daten mehrmals in den aufrufenden Kontext zurückzugeben, besteht darin, Rückrufe und keine Versprechen zu verwenden, da Versprechen nicht dafür erstellt wurden, auf diese Weise zu funktionieren.Wenn Sie den Rückgabewert des Versprechens ändern müssen, geben Sie einfach einen neuen Wert zurück
then
und verketten Sie nextthen
/catch
onquelle
Es gibt keine klare Möglichkeit, Versprechen mehrmals zu lösen, da sie erledigt sind, da sie gelöst wurden. Der bessere Ansatz hier ist, ein vom Beobachter beobachtbares Muster zu verwenden, zum Beispiel habe ich folgenden Code geschrieben, der das Socket-Client-Ereignis beobachtet. Sie können diesen Code erweitern, um Ihre Anforderungen zu erfüllen
quelle
Sie können Tests schreiben, um das Verhalten zu bestätigen.
Wenn Sie den folgenden Test ausführen, können Sie daraus schließen
Sie können auch meinen Blog-Beitrag für Details überprüfen .
quelle
Was Sie tun sollten, ist ein ng-if an Ihrem Haupt-ng-Ausgang anzubringen und stattdessen einen Ladespinner zu zeigen. Sobald Ihr Gebietsschema geladen ist, zeigen Sie den Ausgang an und lassen die Komponentenhierarchie rendern. Auf diese Weise kann Ihre gesamte Anwendung davon ausgehen, dass das Gebietsschema geladen ist und keine Überprüfungen erforderlich sind.
quelle