Что такое async/await в Swift?

Ответ

async/await — это модель асинхронного программирования в Swift, которая позволяет писать последовательный, легко читаемый код для асинхронных операций, заменяя цепочки completion handlers ("callback hell").

Основные концепции:

  • async — ключевое слово, которым помечается асинхронная функция. Такая функция может быть приостановлена.
  • await — ключевое слово, указывающее точку, где выполнение может быть приостановлено до завершения асинхронной операции. Поток при этом не блокируется.
  • Task — единица работы, в которой выполняется асинхронный код.

Пример:

// Асинхронная функция для загрузки данных
func fetchUserData() async throws -> User {
    let url = URL(string: "https://api.example.com/user")!
    // `await` приостанавливает функцию, пока данные не будут загружены
    let (data, _) = try await URLSession.shared.data(from: url)
    return try JSONDecoder().decode(User.self, from: data)
}

// Вызов асинхронной функции
Task {
    do {
        let user = try await fetchUserData()
        await MainActor.run {
            // Обновление UI должно происходить на главном потоке
            self.updateUI(with: user)
        }
    } catch {
        print("Failed to fetch user: (error)")
    }
}

Преимущества:

  • Улучшенная читаемость: Код выглядит как синхронный.
  • Упрощенная обработка ошибок: Используется привычный механизм try/catch.
  • Безопасность: Компилятор помогает избежать распространенных ошибок (например, вызов асинхронного кода не из асинхронного контекста).

Важные нюансы:

  • Нативно поддерживается с iOS 15, macOS 12, tvOS 15, watchOS 8.
  • Для обратной совместимости с более старыми API используется withCheckedContinuation.
  • Для работы с главным потоком используется MainActor.

Ответ 18+ 🔞

Давай разберём эту штуку, которая всех так взбудоражила. async/await, блядь. Ну, наконец-то, ёпта! Вместо того чтобы писать эти ебуччие цепочки комплишн-хэндлеров, где к концу уже забываешь, что в начале делал, и код похож на лапшу, которую кот сука собака навертел.

В чём соль, блядь?

  • async — это как бирочка на функции: «Эй, я могу зависнуть, не жди меня тут, иди делай другие дела». Не блокирует поток, просто приостанавливается, хитрая жопа.
  • await — это точка, где ты говоришь: «Ладно, я тут подожду, пока ты там своё дело сделаешь». Ключевое — поток-то не блокируется, система может в это время другую задачу пинать.
  • Task — это типа контейнер, коробка, в которую ты эту асинхронную хуйню складываешь, чтобы она выполнялась.

Смотри, как это выглядит, без всей этой ебалы с колбэками:

// Функция, которая тащит данные из интернета
func fetchUserData() async throws -> User {
    let url = URL(string: "https://api.example.com/user")!
    // Вот тут `await` — стоп, пацаны, ждём ответа от сервака. Но система не тупит!
    let (data, _) = try await URLSession.shared.data(from: url)
    return try JSONDecoder().decode(User.self, from: data)
}

// Как это вызвать
Task {
    do {
        // Красота же! Читается как обычный код. Никаких вложенных { } в { } в { }
        let user = try await fetchUserData()
        // А это чтобы на главный поток вернуться, UI обновить
        await MainActor.run {
            self.updateUI(with: user)
        }
    } catch {
        print("Всё пропало, шеф: (error)") // Ошибки ловятся как у нормальных людей, try/catch
    }
}

Почему это овердохуища?

  • Читаемость, блядь! Смотришь на код и сразу понимаешь, что за чем идёт. Не нужно глазами прыгать по замыканиям.
  • Ошибки теперь не нужно в десять разных мест пробрасывать — один do/catch и делу конец.
  • Компилятор умный стал, он тебе подскажет, если ты попытаешься асинхронную хуйню из обычного места вызвать — сразу «чё за муда?».

Но есть подводные, блядь, камни:

  • Работает нативно только с iOS 15, macOS 12 и так далее. Если нужно со старьём работать, придётся использовать withCheckedContinuation — это такой костыль, но рабочий.
  • Чтобы тронуть UI, надо явно вернуться на главный поток через MainActor. Не забывай, а то приложение рухнет, и будешь думать, что за пизда с ушами.

В общем, вещь нужная. Не панацея, конечно, но жить стало проще, волнение ебать упало.