2017-12-13 6 views
1

Ich habe einige Code, der in einem promise verpackt ist. Dieser Code geht und bearbeitet einige Datensätze in einem Remote-DB und kehrt mit der Anzahl der bearbeiteten Datensätze zurück. Wenn die Anzahl der bearbeiteten Datensätze größer als 0 ist (d. H. Etwas Arbeit wurde getan), würde ich die gleiche Methode immer wieder ausführen, bis ich eine 0 zurückbekomme (d. H., Es müssen keine Datensätze mehr bearbeitet werden).Wie kann ich das gleiche Versprechen je nach dem Ergebnis des vorherigen Laufs erneut ausführen?

Ich habe verschiedene Wege ausprobiert, aber sie alle enden nicht (d. H. Die Auflösung wird nicht aufgerufen) oder sie laufen nicht richtig.

Erste Version Ich habe versucht:

const doEdits =() => { 
    return new Promise((resolve, reject) => { 
    someDB.performEdits() 
    .then(count => { 
     if (count > 0) { 
     doEdits() 
     } else { 
     resolve() 
     } 
    }) 
    .catch(reject) 
    }) 
} 

return new Promise((resolve, reject) => { 
    someDB.init() 
    .then(doEdits) 
    .catch(reject) 
}) 

Zweite Version Ich habe versucht:

const doEdits =() => { 
    return new Promise((resolve, reject) => { 
    someDB.performEdits() 
    .then(count => { 
     resolve(count) 
    }) 
    .catch(reject) 
    }) 
} 

return new Promise((resolve, reject) => { 
    someDB.init() 
    .then(doEdits) 
    .then(count => { 
    if (count > 0) { 
     return doEdits() // 'doEdits()' did not work... 
    } else { 
     resolve() 
    } 
    }) 
    .catch(reject) 
}) 

Sämtliche Vorschläge sind willkommen.

+0

Sie lösen nicht nach 'doEdits' auf. Versprechen müssen immer am Ende "aufgelöst" oder "abgelehnt" werden. – Eric

+0

@ErikKralj, wenn Sie über das erste Beispiel sprechen, dann nach dem 'if (count> 0)', dann müsste ich ein '.then (...)' danach machen und das zurückgegebene Ergebnis überprüfen und mach es immer wieder etc ... –

Antwort

3

Ja, Sie riefen niemals resolve in der if Branche. Aber Sie sollten hier sowieso keine resolve Funktion verwenden, vermeiden Sie die Promise constructor antipattern! Just do

function doEdits() { 
    return someDB.performEdits().then(count => { 
    if (count > 0) { 
     return doEdits(); 
    } else { 
     return undefined; // ??? 
    } 
    }); 
} 

return someDB.init().then(doEdits); 
+0

Das klappt! - Vielen Dank –

1

nicht Spaghetti Machen Sie

Sie sollten wirklich nicht eine Reihe von Versprechungen erstellen müssen, vor allem, da die zugrunde liegende Bibliothek, die Sie bereits verwenden, ist Ihnen ein promise.This Ansatz Rückkehr

const doEdits = count => { 
    if(count > 0) { 
    return someDB.performEdits().then(doEdits); 
    } 
}; 

return someDB.init() 
    .then(() => { 
    performEdits().then(doEdits) 
    }); 

Dies wird Kette die Versprechungen von den nachfolgenden db Anrufe an das erste Versprechen: Ihr Ziel sollte es ohne all die zusätzlichen Sauce erreichen. Alle nachfolgenden then s (und catch es) werden mit dem zurückgegebenen Versprechen arbeiten (dh warten, bis es aufgelöst oder abgelehnt wird), was möglicherweise durch ein neues Versprechen ersetzt wird, wenn es gelöst wird, bevor es an sie weitergegeben wird.


Warum Ihr Code nicht

funktionierten Wenn Sie sich entscheiden Sie ein Versprechen instanziiert gehen, haben Sie die Verantwortung für die Handhabung der Entschlossenheit genommen und Rückrufe ablehnen - und Ihr Selbst verpflichtet zur Rückruf-Hölle. Genau die Art von Dingen, die Versprechen lösen sollen.

In beiden Schnipsel, sobald Sie count > 0 und rufen Sie in doEdits sehen, verlassen Sie den vorherigen Versprechen, instanziiert ein neues, und mit einer Spur von un resolve d Versprechen in Ihrem Gefolge landen. Sie müssten die Auflösungs- und Ablehnungsfunktionen in das neue Versprechen übernehmen und sicherstellen, dass sie bei Bedarf aufgelöst oder zurückgewiesen werden, wenn das neue Versprechen verfällt oder abgelehnt wird. wenn performEdits Iteration 33 Spuck

Diese

function doEdits(previousPromise) { 
    someDB.performEdits() 
    .then((count) => { 
    if(count > 0) { 
     doEdits(this); 
    } else { 
     resolve(); 
    } 
    }) 
}; 

return new Promise((resolve, reject) => { 
    someDB.init() 
    .then(() => { 
    someDB.performEdits() 
    .then((count) => { 
     if(count > 0) { 
     doEdits(this); 
     } else { 
     resolve(); 
     } 
    }) 
    }) 
}); 

tue nicht Weil es verschwenderisch ist, und auch die Entscheidung nicht handhaben. Theoretisch könnte das funktionieren, aber es ist viel schwieriger darüber nachzudenken.

Verwandte Themen