Як відхилити обіцянку зсередини, тоді функціонувати


85

Це, мабуть, безглузде питання, але середній ланцюжок обіцянок, як відхилити обіцянку зсередини однієї з тодішніх функцій? Наприклад:

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


1
throw validationError
kavun

> <У мене було відчуття, що це буде щось безглузде / легке. Думаю, я постійно думав, що мені доведеться викликати спеціальну функцію відхилення або натомість повернути невдалу обіцянку. Отже, всередині обіцянки / thenable, будь-яке повернене значення, яке не є новим Promise, буде вважатися вирішеним значенням? І якщо я викину помилку, це те саме, що повернути негайно відхилену обіцянку? Якщо ви опублікуєте це як відповідь, я прийму це.
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 Я мав на увазі: p.then(function() { doAsync(function() { throw new Error("won't catch"); }); }); EDIT: о гаразд, я перечитав ваш коментар, я повністю з вами, ми на одній сторінці! Я хотів вказати це на ОП :)
Майк Глісон-молодший Кутюр'є

1
@MikeGleasonjrCouturier: Так, саме про це я говорив. І doAsync(function() { return Promise.reject(new Error("won't catch, won't throw")); })там теж не працює - це просто мовчки. Це справді повинно бути, doAsync().then(function() { throw new Error("will be caught"); })коли ви працюєте з обіцянками.
Бергі,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.