жду Promise.reject или выбросить ошибку, чтобы выручить? - PullRequest
0 голосов
/ 29 мая 2018

Я реорганизую свои коды цепочки обещаний в асинхронном / ожидающем стиле.Одна из причин для этого заключается в том, что я хочу, чтобы один блок перехвата обрабатывал все ситуации с ошибками (как описано здесь Понимание отклонения обещания в node.js )

Мой вопрос: когда я нажимаюошибка синхронизации, я должен вызвать await Promise.reject или throw error, чтобы выручить процесс?Я знаю, что в любом случае будет работать, но я предпочитаю throw error.Я уже знаю, что получил неверный результат, почему я должен ждать?Использование throw для немедленного прекращения потока управления кажется лучшим вариантом.

Я не говорю о цепочке обещаний (весь смысл моего вопроса), поэтому я не думаю, что поток JavaScriptОбещания - отвергни против брось ответил на мой вопрос.

Я прочитал статью Обработка ошибок в Node.js Не думаю, что это также дает ответ.Но в нем говорилось:

Данная функция должна доставлять операционные ошибки либо синхронно (с броском), либо асинхронно (с обратным вызовом или источником событий), , но не оба .... В общем, использование throw и ожидание, что вызывающая сторона использует try / catch, довольно редко ...

Мои асинхронные функции могут возвращать Promise.reject.Поэтому я обеспокоен введением двух способов доставки ошибок, как в этой статье.

try {
   let result = await aysncFunc().
   if (!isResultValid(result)) { //isResultValid() is sync function 
      await Promise.reject('invalid result')
      //or throw 'invalid result'
   }
   ... //further processing
}
catch (error) {
  ...
}

1 Ответ

0 голосов
/ 29 мая 2018

Семантически правильно использовать 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.

...