Как отвергнуть обещание изнутри, затем функция

86

Вероятно, это глупый вопрос, но в середине цепочки обещаний, как вы отклоняете обещание изнутри одной из функций then? Например:

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

Больше нет ссылки на исходную функцию разрешения / отклонения или PromiseResolver. Я просто должен добавить return Promise.reject(validationError);?

Chinabuffet
источник
1
throw validationError
kavun
> <У меня было ощущение, что это будет что-то глупое / легкое. Думаю, я все время думал, что мне нужно вызвать специальную функцию отклонения или вместо этого вернуть неудавшееся обещание. Итак, внутри обещания / thenable любое возвращаемое значение, не являющееся новым обещанием, будет считаться разрешенным значением? И если я выдаю ошибку, это то же самое, что вернуть немедленно отклоненное обещание? Если вы опубликуете это как ответ, я его приму.
chinabuffet
Вы, вероятно, ищете здесь принятый ответ stackoverflow.com/questions/17800176/…
crad

Ответы:

96

Я просто должен добавить return Promise.reject(validationError);?

Да. Однако это сложно только в jQuery, с библиотекой, совместимой с Promise / A +, вы также можете просто

throw validationError;

Тогда ваш код будет выглядеть как

someActionThatReturnsAPromise()
    .then(modifyResource)
    .then(function(modifiedResource) {
        if (!isValid(modifiedResource))
            throw getValidationError(modifiedResource);
        // else !
        return modifiedResource;
    })
    .catch(function() {
        // oh noes
    });
Берги
источник
3
Это обычное дело? Это широко используется? Мне плохо это делать, потому что, если где-то в коде пропадет .catch, все приложение взорвется с непогрешимой ошибкой ..
Андрей Попов
3
Обратите внимание, что в библиотеке, совместимой с Promise / A +, вы можете использовать throw, потому что handlerfor then- это синхронизация и исключение можно перехватить. Если обработчик является асинхронным, он должен вернуть обещание, чтобы в конечном итоге отклонить. Поэтому для меня всегда имеет смысл возвращать Promise.reject () вместо того, чтобы бросать. Потому что, если вы добавите асинхронный обработчик, библиотека не сможет его поймать, и он молча пройдет. Осторожно.
Майк Глисон-младший Кутюрье
1
@MikeGleasonjrCouturier: Не должно быть асинхронных обработчиков, которые не являются .thenобработчиками обещания :-) Если вы используете не обещанный API, тогда даже return Promise.reject()вам поможет.
Bergi
@Bergi Я имел в виду: p.then(function() { doAsync(function() { throw new Error("won't catch"); }); }); РЕДАКТИРОВАТЬ: о, хорошо, я перечитал ваш комментарий, я полностью с вами, мы на одной странице! Я хотел указать на это OP :)
Майк Глисон-младший Кутюрье
1
@MikeGleasonjrCouturier: Да, именно это я и говорил. И там doAsync(function() { return Promise.reject(new Error("won't catch, won't throw")); })тоже не работает - просто тихо выходит из строя. Это действительно должно быть, doAsync().then(function() { throw new Error("will be caught"); })когда вы работаете с обещаниями.
Берги