Jak odrzucić obietnicę od wewnątrz, to funkcjonuj

85

To prawdopodobnie głupie pytanie, ale w połowie łańcucha obietnic, jak odrzucić obietnicę z wnętrza jednej z ówczesnych funkcji? Na przykład:

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
    });

Nie ma już odniesienia do oryginalnej funkcji rozwiązywania / odrzucania ani do PromiseResolver. Czy mam tylko dodać return Promise.reject(validationError);?

podbródek
źródło
1
throw validationError
kavun
> <Miałem przeczucie, że byłoby to coś głupiego / łatwego. Chyba ciągle myślałem, że muszę wywołać dedykowaną funkcję odrzucania lub zamiast tego zwrócić nieudaną obietnicę. Czyli z wnętrza obietnicy / możliwości, każda zwrócona wartość, która nie jest nową obietnicą, zostanie uznana za rozstrzygniętą wartość? A jeśli wyrzucę błąd, to to samo, co zwrócenie natychmiast odrzuconej obietnicy? Jeśli opublikujesz to jako odpowiedź, zaakceptuję to.
chinabuffet
Prawdopodobnie szukasz akceptowanej odpowiedzi tutaj stackoverflow.com/questions/17800176/ ...
crad

Odpowiedzi:

96

Czy mam tylko dodać return Promise.reject(validationError);?

Tak. Jednak jest to tak skomplikowane tylko w jQuery, z biblioteką zgodną z Promise / A + można również po prostu

throw validationError;

Twój kod będzie wtedy wyglądał

someActionThatReturnsAPromise()
    .then(modifyResource)
    .then(function(modifiedResource) {
        if (!isValid(modifiedResource))
            throw getValidationError(modifiedResource);
        // else !
        return modifiedResource;
    })
    .catch(function() {
        // oh noes
    });
Bergi
źródło
3
Czy to normalna czynność? Czy jest szeroko stosowany? Czuję się źle robi, bo jeśli gdzieś w kodzie .catchbrakuje, cała aplikacja będzie wysadzić z unhalted błędu ..
Andrey Popov
3
Zauważ, że w bibliotece zgodnej z Promise / A + możesz użyć throw, ponieważ handlerfor thenjest synchronizowany, a wyjątek można przechwycić. Jeśli program obsługi jest asynchroniczny, musi zwrócić obietnicę, aby ostatecznie ją odrzucić. Dlatego zawsze zwracanie Promise.reject () zamiast rzucania ma dla mnie sens. Ponieważ jeśli wrzucisz program obsługi asynchronicznej, biblioteka nie może go złapać i po cichu przejdzie. Strzec się.
Mike Gleason jr Couturier
1
@MikeGleasonjrCouturier: Nie powinno być żadnych programów obsługi asynchronicznych, które nie są programami obsługującymi .thenw ramach obietnicy :-) Jeśli używasz nie obiecanego interfejsu API, nawet return Promise.reject()ci pomoże.
Bergi
@Bergi Miałem na myśli: p.then(function() { doAsync(function() { throw new Error("won't catch"); }); }); EDYCJA: och ok, ponownie przeczytałem twój komentarz, jestem całkowicie z tobą, jesteśmy na tej samej stronie! Chciałem zwrócić to uwagę na OP :)
Mike Gleason jr Couturier
1
@MikeGleasonjrCouturier: Tak, dokładnie to powiedziałem. I tam doAsync(function() { return Promise.reject(new Error("won't catch, won't throw")); })też nie działa - po prostu cicho zawodzi. Naprawdę powinno tak być, doAsync().then(function() { throw new Error("will be caught"); })gdy pracujesz z obietnicami.
Bergi