Семантически правильно использовать throw
в потоке управления обещаниями, как правило, это предпочтительный способ выхода из цепочки обещаний.
В зависимости от стиля кодирования, await Promise.reject(...)
может использоваться для разграничения между реальными ошибкамии ожидаемые отклонения.Отклоненное обещание со строковой причиной допустимо, но throw 'invalid result'
считается проблемой стиля, которая может быть решена с помощью правил линтера , поскольку принято использовать Error
экземпляров в качестве исключений.
Причина, почемуэто важно потому, что строковые исключения не могут быть обнаружены с помощью instanceof Error
и не имеют свойства message
, поэтому запись в журнал ошибок, как console.warn(error.message)
, приведет к неясным undefined
записям.
// ok
class Success extends Error {}
try {
throw new Success('just a friendly notification');
} catch (err) {
if (!(err instanceof Success)) {
console.warn(err.message);
throw err;
}
}
// more or less
const SUCCESS = 'just a friendly notification';
try {
await Promise.reject(SUCCESS);
} catch (err) {
if (err !== SUCCESS)) {
console.warn(err.message);
throw err;
}
}
// not ok
try {
throw 'exception';
} catch (err) {
if (typeof err === 'string') {
console.warn(err);
} else {
console.warn(err.message);
}
throw err;
}
Поскольку invalid result
на самом деле является ошибкой, разумно сделать ее одной:
throw new TypeError('invalid result');
Я не говорю о цепочке обещаний (весь смысл моего вопроса), поэтому я недумаю, что поток обещаний JavaScript - отклонить или бросить ответил на мой вопрос.
async
- это синтаксический сахар для цепочки обещаний, поэтому все пункты, применимые к обещаниям, применимы и к async
.
Могут быть случаи, когда бросаниеОшибка - это не то же самое, что отклонение обещания, но они характерны для других реализаций обещаний, таких как AngularJS $q
, и не влияют на обещания ES6.Синхронная ошибка в конструкторе Promise
приводит к исключению, это также не относится к async
.