Come rifiutare una promessa dall'interno e poi funzionare


86

Questa è probabilmente una domanda sciocca, ma a metà catena di promesse, come si rifiuta una promessa dall'interno di una delle funzioni then? Per esempio:

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

Non c'è più un riferimento alla funzione di risoluzione / rifiuto originale o al PromiseResolver. Devo solo aggiungere return Promise.reject(validationError);?


1
throw validationError
kavun

> <Avevo la sensazione che sarebbe stato qualcosa di sciocco / facile. Immagino di aver continuato a pensare che dovevo chiamare una funzione di rifiuto dedicata o restituire invece una promessa fallita. Quindi, dall'interno di una promessa / quindi, qualsiasi valore restituito che non è una nuova promessa sarà considerato il valore risolto? E se lancio un errore, è come restituire una Promessa rifiutata immediatamente? Se lo pubblichi come risposta, lo accetto.
chinabuffet

Probabilmente si sta cercando la risposta accettata qui stackoverflow.com/questions/17800176/...
crad

Risposte:


96

Devo solo aggiungere return Promise.reject(validationError);?

Sì. Tuttavia, è così complicato solo in jQuery, con una libreria compatibile con Promise / A + potresti anche semplicemente

throw validationError;

Quindi il tuo codice sarebbe quindi simile

someActionThatReturnsAPromise()
    .then(modifyResource)
    .then(function(modifiedResource) {
        if (!isValid(modifiedResource))
            throw getValidationError(modifiedResource);
        // else !
        return modifiedResource;
    })
    .catch(function() {
        // oh noes
    });

3
È una cosa normale da fare? È ampiamente utilizzato? Mi dispiace farlo, perché se .catchmanca da qualche parte nel codice , l' intera app esploderà senza errori.
Andrey Popov

3
Nota che in una libreria conforme a Promise / A + puoi usare throw perché il handlerfor thenè sincronizzato e l'eccezione può essere rilevata. Se il gestore è asincrono, deve restituire una promessa da rifiutare alla fine. Quindi restituire sempre Promise.reject () invece di lanciare ha senso per me. Perché se lanci un gestore asincrono, la libreria non può catturarlo e passerà silenziosamente. Attenti.
Mike Gleason jr Couturier

1
@MikeGleasonjrCouturier: Non dovrebbero esserci gestori asincroni che non siano .thengestori su una promessa :-) Se stai usando un'API non promessa, allora anche return Promise.reject()ti aiuterà.
Bergi

@Bergi volevo dire: p.then(function() { doAsync(function() { throw new Error("won't catch"); }); }); EDIT: oh ok ho riletto il tuo commento, sono totalmente con te, siamo sulla stessa pagina! Volevo segnalarlo all'OP :)
Mike Gleason jr Couturier

1
@MikeGleasonjrCouturier: Sì, è esattamente quello che stavo dicendo. E doAsync(function() { return Promise.reject(new Error("won't catch, won't throw")); })non funziona nemmeno lì - fallisce silenziosamente. Dovrebbe davvero essere doAsync().then(function() { throw new Error("will be caught"); })quando lavori con le promesse.
Bergi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.