Я прочитал несколько статей на эту тему, но мне все еще не ясно, есть ли разница между Promise.reject
выдачей ошибки. Например,
Использование Promise.reject
return asyncIsPermitted()
.then(function(result) {
if (result === true) {
return true;
}
else {
return Promise.reject(new PermissionDenied());
}
});
Используя бросок
return asyncIsPermitted()
.then(function(result) {
if (result === true) {
return true;
}
else {
throw new PermissionDenied();
}
});
Я предпочитаю использовать throw
просто потому, что он короче, но мне было интересно, есть ли преимущество одного над другим.
javascript
promise
Naresh
источник
источник
.then()
Обработчик ловит брошенное исключение и превращает его в отклоненном обещание автоматически. Поскольку я читал, что сгенерированные исключения не особенно быстро выполняются, я предполагаю, что возвращение отклоненного обещания может быть выполнено немного быстрее, но вам придется разработать тест в нескольких современных браузерах, если это важно знать. Я лично использую,throw
потому что мне нравится удобочитаемость.throw
является то, что это не приведет к отклонению обещания, если оно будет выдано из асинхронного обратного вызова, такого как setTimeout. jsfiddle.net/m07van33 @ Blondie ваш ответ был правильным.reject
его из списка параметров.Ответы:
Нет преимущества в использовании одного против другого, но есть особый случай, когда
throw
он не будет работать. Тем не менее, эти случаи могут быть исправлены.Каждый раз, когда вы находитесь внутри обещания обратного вызова, вы можете использовать
throw
. Однако, если вы находитесь в любом другом асинхронном обратном вызове, вы должны использоватьreject
.Например, это не сработает:
Вместо этого вы остаетесь с нерешенным обещанием и необдуманным исключением. Это тот случай, когда вы хотите использовать вместо этого
reject
. Однако это можно исправить двумя способами.источник
throw error
, иreturn Promise.reject(err)
это то, о чем ОП просил нас сравнить. Именно поэтому вы не должны помещать асинхронные обратные вызовы в обещания. Пообещайте все, что асинхронно, и тогда у вас нет этих ограничений.Array#forEach
) и с ними, бросание внутри них будет работать.throw
они не будут работать, а вместо этогоPromise.reject
- лучший выбор. Однако фрагменты не зависят от любого из этих двух вариантов и дают одинаковый результат независимо от того, что вы выберете. Я что-то пропустил?reject
который был переданnew Promise(fn)
обратному вызову.return Promise.reject()
иthrow
. Он не упоминаетreject
обратный вызов, данный вnew Promise(function(resolve, reject))
конструкции. Таким образом, хотя ваши два фрагмента правильно демонстрируют, когда вам следует использовать обратный вызов разрешения, вопрос OP был не в этом.Другим важным фактом является то, что
reject()
НЕ завершает поток управления, какreturn
оператор. В отличие отthrow
этого прекращается контроль потока.Пример:
против
источник
return reject()
, чтобы следующая строка не выполнялась.return reject()
это просто сокращение,reject(); return
т. Е. То, что вы хотите - это завершить поток. Возвращаемое значение исполнителя (переданной функцииnew Promise
) не используется, поэтому это безопасно.Да, самое большое отличие в том, что reject - это функция обратного вызова, которая выполняется после того, как обещание отклонено, тогда как throw не может использоваться асинхронно. Если вы решили использовать отклонение, ваш код продолжит работать в обычном асинхронном режиме, в то время как throw будет определять приоритет завершения функции распознавателя (эта функция будет запущена немедленно).
Пример, который я видел, который помог мне прояснить проблему, состоял в том, что вы можете установить функцию Timeout с помощью reject, например:
Выше не могло бы быть возможно написать с броском.
В вашем небольшом примере разница в неразличимости, но при работе с более сложной асинхронной концепцией разница между ними может быть радикальной.
источник
TLDR: функцию трудно использовать, когда она иногда возвращает обещание, а иногда выдает исключение. При написании асинхронной функции предпочитайте сигнализировать об ошибке, возвращая отклоненное обещание
Ваш конкретный пример запутывает некоторые важные различия между ними:
Поскольку вы обрабатываете ошибки внутри цепочки обещаний, сгенерированные исключения автоматически преобразуются в отклоненные обещания. Это может объяснить, почему они кажутся взаимозаменяемыми - это не так.
Рассмотрим ситуацию ниже:
Это будет анти-паттерном, потому что вам нужно будет поддерживать как асинхронные, так и синхронизирующие ошибки. Это может выглядеть примерно так:
Не хорошо, и именно здесь
Promise.reject
(доступно в глобальном масштабе) приходит на помощь и эффективно дифференцируется отthrow
. Рефактор теперь становится:Теперь это позволяет вам использовать только один
catch()
для сетевых сбоев и синхронную проверку ошибок на отсутствие токенов:источник
Promise.reject
илиthrow
когда вы хотите вернуть отклоненное обещание (обещание, которое перейдет к следующему.catch()
).checkCredentials(x).then(onFulfilled).catch(e) {}
, и иметьcatch
ручку как случая отклонения, так и выданного сообщения об ошибке?Пример, чтобы попробовать. Просто измените isVersionThrow на false, чтобы использовать reject вместо throw.
источник