Обещание JavaScript: обработчик отклонения против catch [duplicate]

1

Я сталкивался с несколькими приложениями, где использование catch является более предпочтительным, чем rejectHandler. Например: предпочтение

new Promise.then(resolveHandler).catch()

вместо

new Promise().then(resolveHandler, rejectHandler).catch()

Есть ли конкретная причина для этого?

я нахожу

new Promise().then(resolveHandler, rejectHandler).catch()

быть более полезным, потому что

  1. Я могу использовать rejectHandler для решения спроектированного/ожидаемого сценария ошибки, где вызывается Promise.reject.
  2. Я могу использовать блок catch для устранения неизвестных/неожиданных ошибок программирования/времени выполнения.

Кто-то знает какую-то конкретную причину, почему rejectHandler не используется много?

PS Я знаю о новых альтернативах в ES6, но мне просто интересно знать это.

Обновление: Я ЗНАЮ, КАК rejectHandler и лови работает. Вопрос в том, почему я вижу, что все больше людей используют только catch поверх rejectHandler и catch? Это лучшая практика или есть какое-то преимущество?

Обновление (добавив ответ сюда): Нашел ответ, который искал из первых рук. Причина не только в том, что ошибка в reject обрабатывается catch, это в основном из-за цепочки. Когда мы объединяем в цепочку prom.then.then.then.then, шаблон отклонения оказывается немного сложным, поскольку вы не захотите реализовать обработчик отклонений, просто чтобы переслать rejectData вверх по цепочке. Использование только обещания/затем/вылова вместе с разрешением/возвратом/броском оказывается очень полезным для создания цепочки из N чисел объектов. @Боб-Фангер (принятый ответ) тоже решил эту часть. Например:

getData(id) {
        return service.getData().then(dataList => {
            const data = dataList.find(data => {
                return data.id === id;
            });
            if (!data) {
                // If I use Promise.reject here and use a reject handler in the parent then the parent might just be using the handler to route the error upwards in the chain
              //If I use Promise.reject here and parent doesn't use reject handler then it goes to catch which can be just achieved using throw.
                throw {
                    code: 404,
                    message: 'Data not present for this ID'
                };
            }
            return configuration;
        });
    }


//somewhere up the chain
....getConfiguration()
            .then(() => {
                //successful promise execution
            })
            .catch(err => {
                if (err.code) {
                    // checked exception
                    send(err);
                } else {
                    //unchecked exception
                    send({
                        code: 500,
                        message: 'Internal Server error: ${err}'
                    });
                }
            });

Использование только этого Все, что мне нужно беспокоиться, это обещание/затем/ловить вместе с разрешением/возвратом/выбросом в любом месте цепочки.

  • 1
    «Это лучшая практика или есть какое-то преимущество?» Просто нужно написать одну функцию вместо двух? Я не думаю, что лучшая практика установилась вокруг этого. Я думаю, что людям просто легче это понять.
  • 1
    «Это лучшая практика или есть какое-то преимущество? » Никаких технических преимуществ (и, следовательно, нет лучшей практики). Как я уже сказал в своем ответе, это действительно зависит от того, что вам нужно для кода.
Показать ещё 6 комментариев
Теги:
promise

3 ответа

4
Лучший ответ

Разница в том, что если ошибка возникает в разрешенииHandler, она не будет обрабатываться откатомHandler, который обрабатывает только отклонения в первоначальном обещании.

Отрицательный Хэндлер не используется в сочетании с уловкой, потому что большую часть времени мы заботимся только о том, что что-то пошло не так.
Создание только одного обработчика ошибок делает код более понятным.

Если конкретное обещание в цепочке должно обрабатываться по-разному, что может быть причиной использования rejectHandler, но я, вероятно, напишу catch().then().catch() Then catch().then().catch() в этом случае.

  • 0
    Интересное объяснение. Что касается вашей точки зрения, «rejectHandler не используется в сочетании с catch так часто, потому что большую часть времени мы заботимся только о том, что что-то пошло не так». Правда, мы думаем только о том, что пошло не так, хотя я со временем это осознал хорошо подумать, если это ожидаемый, неправильный или неожиданный
1

Ни один из них более полезен, чем другой. Как отклоненный обработчик, так и обратный вызов catch вызывается при ошибке или обещание отклоняется.

Нет никакой "лучшей практики" для использования друг над другом. Вы можете видеть, что код использует тот или иной, но он будет основан на том, чего должен достичь код. Программист может захотеть поймать ошибку в разное время в цепочке и обработать ошибки, возникающие в разное время по-разному.

Надеюсь, следующее поможет объяснить, что я имею в виду:

somePromise
  .then(
      function() { /* code when somePromise has resolved */ },
      function() { /* code when somePromise has thrown or has been rejected. An error thrown in the resolvedHandler will NOT be handled by this callback */ }
   );

somePromise
  .then(
      function() { /* code when somePromise has resolved */ }
   )
   .catch(
      function() { /* code when somePromise has thrown or has been rejected OR when whatever has occurred in the .then chained to somePromise has thrown or the promise returned from it has been rejected */ }
   );

Обратите внимание, что в первом фрагменте, если обработчик разрешен, тогда нет обработанного обработчика (или catch callback), который может уловить ошибку. Ошибка, вызванная разрешенным обратным вызовом, не будет улавливаться отвергнутымHandler, который указан как второй аргумент для. .then

  • 0
    Спасибо. «Не существует« наилучшей практики »для использования одного над другим. Вы можете видеть, что код использует один или другой, но его использование будет основано на том, чего должен достичь код». Это объясняет
0

Как указано в сообщении, предоставление разрешения и отклонения обработчика в том же призыве к. .then позволяет отказаться от предыдущего обещания отдельно от ошибок, брошенных внутри, или возврата отклоненного обещания от обработчика успеха.

Поскольку обработчик отклонения, возвращающийся без ошибки, возобновляет фуфилированный канал цепочки обещаний, последний обработчик улова не будет вызываться, если предыдущий обработчик отклонения возвращается нормально.

Затем этот вопрос переходит к вариантам использования, стоимости разработки и уровня знаний.

Случаи применения

В теории форма два параметра then вызова может быть использована, чтобы повторить операцию. Но поскольку жестко закодированные цепочки обещаний настроены статически, повторная операция не является простой. Более простой способ повторить попытку может заключаться в использовании функции async с утверждениями try-catch, await обещания, которые могут потребоваться повторить, как в этом коде концепции:

async function() {
    let retries = 3;
    let failureErr = null;
    while( retries--) {
       try {
          var result = await retryableOperationPromise() 
          return result;
       }
       catch( err) {
          failureErr = err;
       }
     }
     throw failureErr // no more retries
}

Другие варианты использования могут не распространяться.

Стоимость разработки или коммерческих решений.

Если говорить о том, что пользователь повторит попытку позже, он может быть дешевле, чем что-либо делать с конкретными причинами отказа от обещаний. Например, если я попытаюсь заказать рейс за полночь, когда авиакомпании повысят цены, мне обычно говорят "произошла ошибка, повторите попытку позже", потому что цена, которую я дал в начале бронирования, не будет соблюдена.

Знание (<мнение>)

Я подозреваю, что использование обещаний часто может основываться на примере, а не на глубоком знании предмета. Также возможно, что руководители программ хотят, чтобы база кода была максимально простой для менее опытных разработчиков (вероятно, проблема с затратами).

"Лучшая практика" может действительно не применяться для принятия решений о том, как использовать обещания, если использование действительно. Некоторые разработчики и менеджеры будут избегать некоторых форм использования в принципе, но не всегда, исходя из технических достоинств.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню