2016-07-29 41 views
1

Ich habe die Situation einer Kette von ES6 thenables/verspricht. Das erste Versprechen in der Kette ist in Wirklichkeit eine asynchrone Methode, die bestimmt, ob ein Cache überhaupt erst aktualisiert werden darf und die nachfolgenden Methoden in der Kette die eigentliche Aktualisierung durchführen.Gibt es eine elegantere und intuitivere Möglichkeit, aus einer ES6 Promise-Kette auszubrechen?

Die Sache ist, dass, wenn die erste Methode bestimmt, dass ich eigentlich nicht den Cache aktualisieren sollte, ich aus der Kette bombardieren will .... Ich brauche den Rest nicht zu tun.

Die einzige Möglichkeit, dies zum Laufen zu bringen, ist, das Ergebnis der Testmethode und der jeweils nachfolgenden .hen() in der Kette zu speichern, um zu testen, ob man tatsächlich etwas macht oder ein zurückgibt einfache Promise.resolve (null).

Das scheint wie ein Haufen extra dummer Code, die nicht unbedingt da sein müssten.

Mein Code unten funktioniert .... Fehlerbehandlung ist korrekt .... aber gibt es eine bessere Möglichkeit, diese Art von Muster zu codieren, wo Sie nur bedingt mit einer Kette fortfahren wollen? Eine Möglichkeit, die Antwort nicht zu speichern und dann eine Promise.resolve() auf jedes then() zu zwingen?

function asyncRefreshCache(wDb, forceRefresh) { 
    var cachedDataVersions; 
    var allowRefresh; 
    return wDb.asyncCacheRefreshAllowed(forceRefresh) // Here I test whether I am allowed to really refresh the cache. 
     .then(function (ar) { 
      allowRefresh = ar; 
      return allowRefresh 
       ? wDb.asyncGetCacheDataVersionsForRefresh() // Only do this if allowed above. 
       : Promise.resolve(null); //Yuck. Would love to just break out. But how? 
     }) 
     .then(function (dataVersions) { 
      cachedDataVersions = dataVersions; 
      return allowRefresh 
       ? asyncServerFlexSearch({ dataVersions: dataVersions, includeInactiveFlag: true, onLoadFlag: true }) // Only do this if allowed above. 
       : Promise.resolve(null); //Yuck. Would love to just break out. But how? 
     }) 
     .then(function (serverResponse) { 
      return allowRefresh 
       ? wDb.asyncMergeCleanDataFromServerToCache(cachedDataVersions, serverResponse) // Only do this if allowed above. 
       : Promise.resolve(null); //Yuck. Would love to just break out. But how? 
     }); 
} 

EDIT: Diese Frage als Duplikat wegen ähnlicher Fragen zu Q Versprechungen und JQuery Promises markiert wurde. Und JQuery Versprechen sind nicht wirklich Versprechen. Also war meine anfängliche Hoffnung, dass die Spezifikation und die Implementierung für ES6-Versprechen diesem scheinbar wichtigen Bedarf und Anwendungsfall entsprechen würde. Es scheint, dass dies möglicherweise nicht der Fall ist. Die Antworten auf diese anderen Fragen mögen die "richtige" Antwort auf diese Frage sein, aber es geht nicht um ES6-Versprechen. Das scheint mir anders zu sein.

+0

Ich glaube nicht, es ist egal, dass das Duplikat nicht über ES6 Versprechen ist, das Muster ist genau das gleiche. – Bergi

Antwort

3

aber gibt es einen besseren Weg, um diese Art von Muster zu codieren, wo Sie nur mit einer Kette bedingt fortfahren wollen ?

Sie könnten throw ein Error oder verwenden Promise.reject() von .then(), behandeln Fehler und Prozessfehlermeldung oder abgelehnt Versprechen Grund an .catch()

+0

Ich schätze die Antwort, und ich sehe, wie es funktionieren würde, aber die Verwendung von Ausnahmen (oder Ablehnungen) zur Kontrolle des erwarteten Programmflusses scheint problematisch. Und auch nicht besonders lesbar. Es fühlt sich genauso problematisch an wie meine Lösung. Ich frage mich, ob die beste Lösung ist, nur das Versprechen zu nisten. –

+0

Antwort zeigt nur einen möglichen Ansatz. Sie können auch nach 'null' Wert bei' .then() 'suchen und das existierende Muster bei Frage verwenden. Sie müssen nicht 'Promise.resolve (null)' als '.then()' verwenden, um ein neues 'Versprechen' zurückzugeben; Sie könnten ternär nur mit 'null' als Rückgabewert für verkettete' .then() 'verwenden. Throwing error umgeht '.then (onFulfilled)' – guest271314