2013-06-27 8 views
5

Ich habe eine Frage zu Dojo/Deferred. Ich beginne mit der Frage, gehe dann genauer auf das ein, was ich mache:Wie kann allgemeiner Code ausgeführt werden, nachdem ein verzögertes Dojo-Objekt aufgelöst oder zurückgewiesen wurde?

Gibt es eine Möglichkeit, die gleichen Codezeilen auszuführen, unabhängig vom Ergebnis der zurückgestellten, wie ein finally Block in eine try...catch Aussage? Nach dem, was ich gelesen habe, scheint es nicht so zu sein, aber vielleicht verstehe ich die Dokumentation falsch und wollte das mit der SO-Community bestätigen.

Hier ist, was ich tue:

In Dojo 1.9 (funktioniert auch in 1.8), habe ich eine dojox.widget.Standby (ein Laden Overlay) für eine ContentPane instanziiert, bevor einige Daten geladen werden. Sobald der verzögerte Anruf beendet ist, möchte ich mein Overlay wie unten gezeigt ausblenden:

standby = new Standby({ 
    ... // standby props 
}); 
this.addChild(standby); 
standby.show(); 

queryResults = grid.store.query({ 
    ... // query props 
}); 
queryResults.then(function (results) { 
    if (results) { 
     ... // do something 
    } 

    standby.hide(); 
}, function (error) { 
    ... // handle error 

    standby.hide(); 
}); 

Das funktioniert gut; Ich könnte jedoch vermutlich einen Prozess implementieren, der nach dem verzögerten Abschluss implementiert wird, der mehrere Codezeilen anstatt nur einer einzigen Zeile einnimmt, und ich möchte diese Codezeilen nicht duplizieren. Eine Alternative wäre, eine private Funktion zu erstellen und sie einfach mit einem Einzeiler in jedem Block anzurufen, aber wenn es einen besseren Weg gibt, würde ich lieber diesen Weg nehmen.

Vielen Dank im Voraus!

Antwort

5

Sie können die always-Methode der Promises-API verwenden, um eine Funktion unabhängig davon auszuführen, ob der zugrunde liegende Deferred erfolgreich ist oder fehlschlägt.

queryResult 
    .then(onSuccess, onFailure) 
    .always(function() { 
     standby.hide(); 
    }); 
2

Das ist eine gute Frage. Ein Objekt dojo/Deferred wird ein anderes verzögertes Objekt zurückgeben, wenn Deferred#then aufgerufen wird. Auf diese Weise können Sie einen Unterschied zwischen mehreren Callbacks herstellen, die in einer seriellen Reihenfolge ausgelöst werden. Deshalb glaube ich, Sie so etwas tun kann:

queryResults.then(function (results) { 
    if (results) { 
     ... // do something 
    } 
}, function (error) { 
    ... // handle error 
}).then(function(data){ 
    // This will be fired with data returned from the previous callback. 
    standby.hide(); 
}); 

Sie können see this example fiddle, die eine ähnliche, wenn auch einfach, Anwendungsfall darstellt, in dem unabhängig davon, ob die latenten zurückgewiesen oder aufgelöst, der Rückruf auf die zweite Deferred#then gebrannt nach dem ersten Fehler/Erfolg-Callback.

+0

Sie und @Lucas haben meine Frage, da beide Ihre Antworten sind richtig beantwortet. Ich habe @Lucas die "beste Antwort" gegeben, weil ich denke, dass "immer" eine klarere Absicht darstellt als ein zusätzliches "dann". Aber ich habe deine Antwort für ihre Richtigkeit hochgestimmt. – David

-1
var deferred = new Deferred(); 
deferred.promise.always(function() { alert('ciao'); }); 
+0

Dies scheint nichts über die vorhandenen Antworten hinzuzufügen. – Bergi

+0

ja es tut, erweitert erweitert versprechen, so dass ich die Versprechen Eigenschaft ohne Aufruf der .then() -Funktion und legen Sie die Callback-Funktionen. – max4ever

+0

Die anderen Antworten verwenden '.then()', weil das OP diese outcome-abhängigen Callback-Funktionen ebenfalls benötigt. – Bergi

Verwandte Themen