Wie gehe ich dann mit dem vielversprechenden Wenn-Sonst um?


85

In einigen Fällen muss ich, wenn ich einen Rückgabewert von einem Versprechungsobjekt erhalte, zwei verschiedene then()Vorgänge starten, die von der Bedingung des Werts abhängen, wie z.

promise().then(function(value){
    if(//true) {
        // do something
    } else {
        // do something 
    }
})

Ich denke, vielleicht kann ich es so schreiben:

promise().then(function(value){
    if(//true) {
        // call a new function which will return a new promise object
        ifTruePromise().then();
    } else {
        ifFalsePromise().then();
    }
})

Damit habe ich zwei Fragen:

  1. Ich bin mir nicht sicher, ob es eine gute Idee ist, ein neues Versprechen zu starten und dann ein Versprechen zu verarbeiten.

  2. Was ist, wenn ich die beiden Prozesse brauche, um eine Funktion in der letzten aufzurufen? Es bedeutet, dass sie das gleiche "Terminal" haben

Ich habe versucht, das neue Versprechen zurückzugeben, die ursprüngliche Kette wie folgt beizubehalten:

promise().then(function(value){
    if(//true) {
        // call a new function which will return a new promise object
        // and return it
        return ifTruePromise();
    } else {
        // do something, no new promise
        // hope to stop the then chain
    }
}).then(// I can handle the result of ifTruePromise here now);

Aber in diesem Fall thenfunktioniert der nächste, egal ob er wahr oder falsch ist .

Also, was ist die beste Vorgehensweise, um damit umzugehen?


1
Vielleicht ist dies das, wonach Sie suchen. stackoverflow.com/questions/26599798/… ?
Vinayr

Antworten:


59

Solange Ihre Funktionen ein Versprechen zurückgeben, können Sie die erste von Ihnen vorgeschlagene Methode verwenden.

Die folgende Geige zeigt, wie Sie je nach dem ersten aufgelösten Wert unterschiedliche Verkettungspfade wählen können.

function myPromiseFunction() {
	//Change the resolved value to take a different path
    return Promise.resolve(true);
}

function conditionalChaining(value) {
    if (value) {
        //do something
        return doSomething().then(doSomethingMore).then(doEvenSomethingMore);
    } else {
        //do something else
        return doSomeOtherThing().then(doSomethingMore).then(doEvenSomethingMore);
    }
}

function doSomething() {
    console.log("Inside doSomething function");
    return Promise.resolve("This message comes from doSomeThing function");
}

function doSomeOtherThing() {
    console.log("Inside doSomeOtherthing function");
    return Promise.resolve("This message comes from doSomeOtherThing function");
}

function doSomethingMore(message) {
    console.log(message);
    return Promise.resolve("Leaving doSomethingMore");
}

function doEvenSomethingMore(message) {
    console.log("Inside doEvenSomethingMore function");
    return Promise.resolve();
}

myPromiseFunction().then(conditionalChaining).then(function () {
    console.log("All done!");
}).
catch (function (e) {

});

Sie können auch nur eine bedingte Verkettung vornehmen, das Rückgabeversprechen einer Variablen zuweisen und dann die Funktionen ausführen, die in beide Richtungen ausgeführt werden sollen.

function conditionalChaining(value){
    if (value) {
        //do something
        return doSomething();
    } else{
        //do something else
        return doSomeOtherThing();
    }
}

var promise = myPromiseFunction().then(conditionalChaining);

promise.then(function(value){
    //keep executing functions that should be called either way
});

4

Ich habe ein einfaches Paket für die Verwendung von bedingten Versprechungen geschrieben.

Wenn Sie es ausprobieren möchten:

npm-Seite: https://www.npmjs.com/package/promise-tree

und github: https://github.com/shizongli94/promise-tree

Als Antwort auf Kommentare, in denen gefragt wird, wie das Paket das Problem löst:

1, es hat zwei Objekte.

2, Branch-Objekt in diesem Paket ist ein temporärer Speicherort für die Funktionen wie onFulfilled und onRejected, die Sie in then () oder catch () verwenden möchten. Es gibt Methoden wie then () und catch (), die dieselben Argumente wie die Gegenstücke in Promise verwenden. Wenn Sie einen Rückruf in Branch.then () oder Branch.catch () übergeben, verwenden Sie dieselbe Syntax wie Promise.then () und Promise.catch (). Speichern Sie dann die Rückrufe in einem Array.

3, Bedingung ist ein JSON-Objekt, das die Bedingungen und andere Informationen zum Überprüfen und Verzweigen speichert.

4, Sie geben Bedingungen (boolescher Ausdruck) unter Verwendung des Bedingungsobjekts in Versprechungsrückrufen an. Die Bedingung speichert dann die Informationen, die Sie übergeben. Nachdem alle erforderlichen Informationen vom Benutzer bereitgestellt wurden, verwendet das Bedingungsobjekt eine Methode, um ein vollständig neues Promise-Objekt zu erstellen, das Versprechen-Ketten- und Rückrufinformationen verwendet, die zuvor im Branch-Objekt gespeichert wurden. Ein kleiner kniffliger Teil hier ist, dass Sie (als Implementierer, nicht als Benutzer) das Versprechen, das Sie zuerst manuell erstellt haben, auflösen / ablehnen müssen, bevor Sie die gespeicherten Rückrufe verketten. Dies liegt daran, dass die neue Versprechen-Kette sonst nicht startet.

5, Dank der Ereignisschleife können Verzweigungsobjekte entweder vor oder nach einem Stammversprechen-Objekt instanziiert werden, und sie stören sich nicht gegenseitig. Ich verwende hier die Begriffe "Zweig" und "Stamm", weil die Struktur einem Baum ähnelt.

Beispielcode finden Sie sowohl auf npm- als auch auf github-Seiten.

Übrigens ermöglicht diese Implementierung auch, dass Sie Zweige innerhalb eines Zweigs haben. Und Filialen müssen sich nicht an dem Ort befinden, an dem Sie die Bedingungen überprüfen.


Es sieht so aus, als würden Sie Kommentare anstelle von Antworten bereitstellen. Sobald Sie einen ausreichenden Ruf haben, können Sie jeden Beitrag kommentieren . Überprüfen Sie auch, was ich stattdessen tun kann .
thewaywewere

@thewaywewere, ich habe Implementierungsdetails hinzugefügt, um auf Ihre Anfrage zu antworten.
Szl1919

0

So habe ich es in meinem fetch () gemacht. Ich bin mir nicht sicher, ob dies der richtige Weg ist, aber es funktioniert

 fetch().then(res => res.ok ? res : false).then(res => {
    if (res) {
        //res ok
    } else {
       //res not ok
    }

});
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.