Wie man ein Versprechen von innen ablehnt, funktioniert dann

83

Dies ist wahrscheinlich eine dumme Frage, aber in der Mitte der Versprechenskette, wie lehnen Sie ein Versprechen innerhalb einer der damaligen Funktionen ab? Beispielsweise:

someActionThatReturnsAPromise()
    .then(function(resource) {
        return modifyResource(resource)
    })
    .then(function(modifiedResource) {
        if (!isValid(modifiedResource)) {
            var validationError = getValidationError(modifiedResource);
            // fail promise with validationError
        }
    })
    .catch(function() {
        // oh noes
    });

Es gibt keinen Verweis mehr auf die ursprüngliche Auflösungs- / Ablehnungsfunktion oder den PromiseResolver. Soll ich nur hinzufügen return Promise.reject(validationError);?

Chinabuffet
quelle
1
throw validationError
Kavun
> <Ich hatte das Gefühl, dass es etwas Dummes / Leichtes sein würde. Ich dachte immer wieder, ich müsste stattdessen eine dedizierte Ablehnungsfunktion aufrufen oder ein fehlgeschlagenes Versprechen zurückgeben. Innerhalb eines Versprechens / dann kann jeder zurückgegebene Wert, der kein neues Versprechen ist, als aufgelöster Wert betrachtet werden? Und wenn ich einen Fehler mache, ist das dasselbe wie ein sofort abgelehntes Versprechen zurückzugeben? Wenn Sie das als Antwort posten, werde ich es akzeptieren.
Chinabuffet
Sie suchen wahrscheinlich nach der akzeptierten Antwort hier stackoverflow.com/questions/17800176/…
crad

Antworten:

94

Soll ich nur hinzufügen return Promise.reject(validationError);?

Ja. Es ist jedoch nur in jQuery so kompliziert , mit einer Promise / A + -kompatiblen Bibliothek könnten Sie auch einfach

throw validationError;

Ihr Code würde dann also so aussehen

someActionThatReturnsAPromise()
    .then(modifyResource)
    .then(function(modifiedResource) {
        if (!isValid(modifiedResource))
            throw getValidationError(modifiedResource);
        // else !
        return modifiedResource;
    })
    .catch(function() {
        // oh noes
    });
Bergi
quelle
3
Ist das eine normale Sache? Ist es weit verbreitet? Ich fühle mich schlecht dabei, denn wenn irgendwo im Code etwas .catchfehlt, wird die ganze App mit einem ungehinderten Fehler in die Luft jagen.
Andrey Popov
3
Beachten Sie, dass Sie in einer Promise / A + -kompatiblen Bibliothek throw verwenden können, da das handlerfor thensynchron ist und die Ausnahme abgefangen werden kann. Wenn der Handler asynchron ist, muss er ein Versprechen zurückgeben, um es schließlich abzulehnen. Es macht für mich also Sinn, immer Promise.reject () zurückzugeben, anstatt zu werfen. Denn wenn Sie einen asynchronen Handler einsetzen, kann die Bibliothek ihn nicht abfangen und er wird stillschweigend übergeben. In acht nehmen.
Mike Gleason jr. Couturier
1
@MikeGleasonjrCouturier: Es sollte keine asynchronen Handler geben, die keine .thenHandler für ein Versprechen sind :-) Wenn Sie eine nicht versprochene API verwenden, return Promise.reject()hilft Ihnen dies sogar.
Bergi
@Bergi Ich meinte wie: p.then(function() { doAsync(function() { throw new Error("won't catch"); }); }); EDIT: oh okay, ich habe deinen Kommentar noch einmal gelesen, ich bin total bei dir, wir sind auf der gleichen Seite! Ich wollte das OP darauf hinweisen :)
Mike Gleason jr. Couturier
1
@ MikeGleasonjrCouturier: Ja, genau das habe ich gesagt. Und doAsync(function() { return Promise.reject(new Error("won't catch, won't throw")); })funktioniert dort auch nicht - es scheitert nur lautlos. Es sollte wirklich sein, doAsync().then(function() { throw new Error("will be caught"); })wenn Sie mit Versprechungen arbeiten.
Bergi