Scala for Backend Engineering & Functional Programming · Урок

Обработка ошибок в Future

Реализуйте стратегии корректной обработки исключений и сбоев в асинхронных вычислениях `Future`.

Урок 3 из 311 шагов

«Обработка ошибок в Future» — бесплатный урок Scala for Backend Engineering & Functional Programming на CoddyKit. Это урок 3 из 3. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Scala for Backend Engineering & Functional Programming, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Scala for Backend Engineering & Functional Programming содержит 3 уроков всего.

Обработка сбоев Future

Асинхронные операции могут завершаться с ошибкой! Как и синхронный код может выбрасывать исключения, объект Future может завершиться с ошибкой вместо успешного значения.

Умение корректно обрабатывать такие сбои крайне важно для создания надёжных конкурентных приложений. Без надлежащей обработки ошибок программа может аварийно завершиться или повести себя непредсказуемо.

Результат Future: Try

После завершения Future его результат обёрнут в scala.util.Try. Этот объект Try может быть либо Success(value), либо Failure(exception).

  • Success: содержит вычисленное значение.
  • Failure: содержит возникшее исключение.

Функция обратного вызова onComplete получает этот объект Try, что позволяет обработать оба исхода.

Использование onComplete для обработки ошибок

Метод onComplete является универсальным обработчиком завершения Future. Он принимает функцию, которой передаётся значение типа Try[T].

Вы можете сопоставить объект Try с образцом, чтобы различить успешное и неуспешное завершение.

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Success, Failure}

object Main {
  def main(args: Array[String]): Unit = {
    val failingFuture = Future { 
      if (true) throw new RuntimeException("Oops!")
      10
    }

    failingFuture.onComplete {
      case Success(value) => println(s"Success: $value")
      case Failure(exception) => println(s"Failure: ${exception.getMessage}")
    }

    Thread.sleep(100) // Keep JVM alive for Future to complete
  }
}

Метод recover

recover позволяет обработать исключение и предоставить резервное значение, если Future завершился с ошибкой. Он преобразует Future[T] в другой Future[T].

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

Пример recover

Здесь, если происходит деление на ноль, recover перехватывает ArithmeticException и возвращает Future со значением 0.

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

object Main {
  def main(args: Array[String]): Unit = {
    val resultFuture = Future { 10 / 0 } // This will fail

    val recoveredFuture = resultFuture.recover {
      case e: ArithmeticException =>
        println("Caught ArithmeticException, recovering...")
        0 // Fallback value
    }

    recoveredFuture.foreach(value => println(s"Result: $value"))

    Thread.sleep(100) // Keep JVM alive
  }
}

Метод recoverWith

recoverWith похож на recover, но вместо резервного значения возвращает резервный Future.

Это полезно, когда само действие восстановления включает другую асинхронную операцию или когда Вы хотите повторить исходную операцию.

Пример recoverWith

Если исходный объект Future завершается с ошибкой, recoverWith предоставляет новый объект Future, который пытается выполнить другую операцию или возвращает стандартное асинхронное значение.

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

object Main {
  def main(args: Array[String]): Unit = {
    val primaryOperation = Future { 
      if (true) throw new Exception("Primary failed!")
      100
    }

    val fallbackOperation = Future { 
      println("Running fallback operation...")
      50 
    }

    val finalFuture = primaryOperation.recoverWith {
      case e: Exception =>
        println(s"Primary failed: ${e.getMessage}. Using fallback.")
        fallbackOperation
    }

    finalFuture.foreach(value => println(s"Final result: $value"))

    Thread.sleep(200) // Keep JVM alive
  }
}

Метод fallbackTo

fallbackTo позволяет объединить два объекта Future в цепочку. Если первый Future завершается с ошибкой, его результат игнорируется, а вместо него используется результат второго Future.

В отличие от recoverWith, fallbackTo не анализирует исключение. Он просто говорит: «Если этот объект завершится с ошибкой, попробуйте другой».

Пример fallbackTo

Здесь, если failingFuture завершится с ошибкой, fallbackTo использует результат backupFuture.

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

object Main {
  def main(args: Array[String]): Unit = {
    val failingFuture = Future { 
      if (true) throw new RuntimeException("Network error!")
      "Data from primary"
    }

    val backupFuture = Future { 
      println("Using backup source...")
      "Data from cache"
    }

    val finalResult = failingFuture.fallbackTo(backupFuture)

    finalResult.foreach(value => println(s"Retrieved: $value"))

    Thread.sleep(100) // Keep JVM alive
  }
}

Тест по обработке ошибок

Какой метод следует использовать, если при ошибке Future Вы хотите предоставить альтернативную асинхронную операцию?

Повторение: обработка ошибок Future

Мы рассмотрели основные стратегии обработки ошибок в объектах Future Scala:

  • onComplete: реагирует и на успешное, и на неуспешное завершение с помощью Try.
  • recover: предоставляет резервное значение при возникновении исключения.
  • recoverWith: предоставляет резервный Future при возникновении исключения.
  • fallbackTo: использует резервный Future, если основной завершается с ошибкой, не анализируя ошибку.

Эти методы необходимы для создания устойчивых асинхронных систем!

Можно начать бесплатно

Изучай Scala с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
39
Уроки
143

Часто задаваемые вопросы

Урок «Обработка ошибок в Future» бесплатный?

Да — полный текст урока «Обработка ошибок в Future» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Scala for Backend Engineering & Functional Programming, подпишись на CoddyKit PRO. Курс Scala for Backend Engineering & Functional Programming содержит 3 уроков всего.

Чему я научусь в уроке «Обработка ошибок в Future»?

Реализуйте стратегии корректной обработки исключений и сбоев в асинхронных вычислениях `Future`. Ты практикуешь Scala for Backend Engineering & Functional Programming с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Scala for Backend Engineering & Functional Programming?

Предыдущий опыт не требуется. Scala for Backend Engineering & Functional Programming на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 3.

Сколько времени занимает урок «Обработка ошибок в Future»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Scala for Backend Engineering & Functional Programming?

Да. Каждый урок Scala for Backend Engineering & Functional Programming включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Введение в Future и Promise
  2. Композиция асинхронных операций
  3. Обработка ошибок в Future
← Назад к Scala for Backend Engineering & Functional Programming