2013-09-30 11 views
5

In meinem Skript, ich brauche einen Wörterbuch abrufen codierte Werte in Namen konvertieren:bedingte Versprechen

$.ajax({ 
    // retrieve dictionary 
}) 
.done(function(dictionary){ 
    // convert encoded values into names 
}) 
.done(function(){ 
    // run my application 
}); 

jedoch manchmal das Wörterbuch bereits von einer anderen Anwendung geladen wurde, und in diesem Fall, dass ich dies nicht tun müssen die ajax-Aufruf:

if (dictionary) { 
    // convert encoded values into names 
    // run my application 
} 
else { 
$.ajax({ 
    // retrieve dictionary 
}) 
.done(function(dictionary){ 
    // convert encoded values into names 
}) 
.done(function(){ 
    // run my application 
}); 
} 

Diese if/else-Anweisung ziemlich schwer ist, ist es eine Möglichkeit, es kürzer zu machen:

// load dictionary if needed 
// then run my application 

Hinweis: Ich habe das $ -Zeichen für meinen Pseudocode verwendet, bin aber nicht unbedingt an jQuery gebunden.

+1

Ich mache so ziemlich eine Menge in meinen Anwendungen. Die Sache, die Sie haben, ist, dass, wenn Daten asynchron erfasst werden, dann müssen Sie mit asynchronen Methoden zugreifen, unabhängig davon, ob es bereits erworben wurde oder nicht - Grund ist bei jeder Nutzung, Sie wissen nicht, ob die Daten ist sofort verfügbar oder muss abgeholt werden. –

+0

@ Rote-Bete-Rote Bete können Sie erklären, wie Sie mit asynchronen Methoden auf bereits erfasste Daten zugreifen? Vielleicht eine Antwort mit Code oder Pseudocode posten? – Christophe

+0

Siehe die bereits geposteten Antworten. Das versuchen die Jungs zu erklären. –

Antwort

0

Vielleicht eine falsche Versprechen erstellen mit $ .wenn?

var promise; 
if (dictionary) promise = $.when(dictionary); 
else { 
    promise = $.ajax({ 

    }) 
    .done(function(dictionary){ 
     // convert encoded values into names 
    }); 
} 

promise 
    .done(function(){ 
     // run my application 
    }); 
2

Sie sollten $.ajax() genau einmal aufrufen und das zurückgegebene Versprechen in Ihrer (global-ish) dictionary Variable speichern.

Dann schreiben Sie jedes Mal, wenn Sie das Ergebnis verwenden möchten, einfach dictionary.then(...).
Wenn die AJAX-Anfrage bereits abgeschlossen ist, wird der Rückruf sofort ausgeführt.

+1

Nun, so funktioniert es nicht. Wie ich in der Frage gesagt habe, kann das Wörterbuch, selbst wenn mein Code startet, bereits vorhanden sein (geladen von einem anderen Skript, das ich nicht kontrollieren kann), und in diesem Fall brauche ich nicht einmal den ersten Ajax-Aufruf. Zum Beispiel könnte das Wörterbuch in localStorage gespeichert werden. – Christophe

+0

@Christophe: Setzen Sie dann global auf eine voraufgelöste Verheißung und rufen Sie '.then()' trotzdem auf. – SLaks

+0

ok, das ist was ich versuche zu verstehen, wie man ein bedingtes Versprechen schreibt. – Christophe

3

Dies ist das Muster, das ich verwenden in der Regel:

var done = function() { 
    //continue loading application 
} 

if(!dictionary) { 
    $.ajax({ 

    }) 
     .done(done); 
} else { 
    done.apply(this); 
} 

Ein sehr ähnliches Muster, die immer die Verwendung eines latenten Objekt macht, wird die folgende sein:

var 
    dictionaryDeferred = new $.Deferred(), 
    dictionaryPromise = dictionaryDeferred.promise(); 

if(!dictionary) { 
    $.ajax({ 

    }) 
     .done(function() { 
      //do something with the response 
      dictionaryDeferred.resolve(); 
     }); 
} else { 
    dictionaryDeferred.resolve(); 
} 

dictionaryPromise.then(function() { 
    //continue loading application 
}); 
+0

Danke. Ich mag das zweite Muster besser, weil es das Verketten erleichtert. Ein Problem könnte sein, dass der aufgelöste Wert von dictionaryPromise zwischen den beiden Zweigen nicht konsistent ist (aber in meinem Fall kein Problem, da das Dictionary eine globale Variable ist). – Christophe

+0

Sie müssen 'dictionaryPromise' nicht an beiden Stellen verwenden, an denen das Wörterbuch angefordert werden soll. Sie können es einfach an dieser Stelle verwenden, an der die Anwendung geladen wird, weil Sie noch nach 'if (! Dictionary) 'existiert hier schon oder nicht. – Adam

+0

Warum "neu" mit $ .Deferred() verwenden, wenn die Verwendung von "neu" optional ist? –