2014-12-15 2 views
3

Say У меня есть следующая Promise цепь:Bluebird Promise Отмена

var parentPromise = Promise.resolve() 
    .then(function() { 
    var condition = false; 
    if (condition) { 
     return parentPromise.cancel('valid reason'); 
    } else { 
     return Promise.resolve() 
     .then(function() { 
      var someOtherCondition = true; 
      if (someOtherCondition) { 
      console.log('inner cancellation'); 
      return parentPromise.cancel('invalid reason'); 
      } 
     }); 
    } 
    }) 
    .catch(Promise.CancellationError, function (err) { 
    console.log('throwing'); 
    if (err.message !== 'valid reason') { 
     throw err; 
    } 
    }) 
    .cancellable(); 

выше никогда не входит в catch.

Если мы поменяем condition на true, внутренняя отмена никогда не будет удалена, но catch по-прежнему не срабатывает.

удаляет .cancellable в конце и заменяет все экземпляры parentPromise.cancel() явным throw new Promise.CancellationError() «исправляет» проблему. Почему я не понимаю?

Почему первоначальный подход не работает?

Я использую bluebird 2.3.11.

+0

Я думаю, что вы должны сделать обещание отменимым * первым *, не последним. – Tomalak

+0

Tomalak прав, вы только обещаете вернуть '.catch()' в конце отмены. Родители не могут наследовать от своих детей после факта, но дети будут наследовать от их родителей. – Esailija

ответ

3

cancellable() создает аннулируемые обещания, и только они бросают CancellationError по умолчанию, когда функция cancel вызывается с какой-либо причиной.

В вашем случае вы делаете обещание cancellable только после присоединения обработчика catch. Но обещание еще не cancellable. Таким образом, cancel вызов функции не поднимет Promise.CancellationError.

Вы должны изменить структуру кода, как этот

then(function(..) { 
    ... 
}) 
.cancellable() 
.catch(Promise.CancellationError, function (err) { 
    ... 
}); 

Примечание: я рекомендовал бы многообещающими с красивой функции Promise конструктора. Это похоже на спецификацию ECMA Script 6.

new Promise(function(resolve, reject) { 
    ... 
}); 
+0

Когда я попытался представить обещание с .cancellable() перед моим .catch(), сервер никогда не запускается. –

+0

@AbrahamP Убедитесь, что вы удаляете ';' after' .cancellable'. Если это не проблема, пожалуйста, покажите текущий код. – thefourtheye

+0

Текущий код: https://github.com/apolishch/bookshelf-soft-delete/blob/master/index.js для условия ошибки, заменить строки 20 и 26 возвратом parentPromise.cancel() и добавить строку что просто говорит .cancellable между строками 30 и 31. –

Смежные вопросы