Swift 5.5: Async/Await

Привет

На WWDC 2021 Apple представила асинхронные функции в Swift 5.5. Асинхронные функции позволяют нам выполнять сложные задачи асинхронно, как и некоторые другие языки программирования, такие как JavaScript. Асинхронные функции должны быть определены с помощью ключевого слова async, для вызова асинхронных функций нам нужно использовать ключевое слово await.

. . .

Зачем нужны асинхронные функции?

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

func signUp(completion: @escaping() -> Void) {
    // ...
    pushUserData {
        // ...
        verifyUserEmail {
            // ...
            sendWelcomeEmail {
                // ...
                deleteTemperaryAuthToken {
                    completion()
                }
                // ...
            }
            // ...
        }
        // ...
    }
    // ...
}

В коде нет ничего плохого, просто его немного сложно читать и писать.

Что произойдет, если мы сделаем это?

func signUp(completion: @escaping() -> Void) {
  pushUserData { // ... }
  verifyUserEmail { // ... }
  sendWelcomeEmail { // ... }
  deleteTemperaryAuthToken { // ... }
    
  completion()
}

Поскольку все эти функции являются синхронными, они не будут ждать, пока завершится предыдущая перед выполнением. Например, pushUserData может занять 2 секунды, чтобы сохранить данные в базу данных, но VerifyUserEmail не будет ждать, пока данные будут сохранены. Мы начнем проверять, отправлять приветственные письма, удалять токены аутентификации, прежде чем мы сможем успешно сохранить данные. Что небезопасно, что произойдет, если мы не сможем сохранить данные.

Знакомство с асинхронными функциями

Давайте посмотрим, как асинхронность очищает код. Чтобы создать асинхронную функцию, нам нужно добавить ключевое слово async после параметров. Например:

func signUp() async {
  // ...
}

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

func signUp() async {
  await pushUserData()
  await verifyUserEmail()
  await sendWelcomeEmail()
  await deleteTemperaryAuthToken()
}

Чтобы ключевое слово await работало, функции, которые мы вызываем, также должны быть асинхронными. Итак, они будут:

func pushUserData() async {

}

func verifyUserEmail() async {

}

func sendWelcomeEmail() async {

}

func deleteTemperaryAuthToken() async {

}

Мы также можем возвращать и передавать данные из/в асинхронные функции. В функции pushUserData мы добавляем возвращаемый тип данных после ключевого слова async и возвращаем данные после завершения запроса.

В функции signUp мы сохраняем email и передаем ее другим функциям.

func signUp() async {
  let email = await pushUserData()
  
  await verifyUserEmail(email: email)
  await sendWelcomeEmail(email: email)
  
  await deleteTemperaryAuthToken()
}

func pushUserData() async -> String {
  let user = await // request
  
  return user.email
}

func verifyUserEmail(email: String) async {
  await // request 
}

func sendWelcomeEmail(email: String) async {
  await // request 
}

Заключение

Я надеюсь, что вы увидели преимущества асинхронных функций. Это в основном очищает наш код и делает код более читабельным. Swift — удивительный язык программирования, но, конечно, есть много областей, которые необходимо улучшить. К счастью, Apple продолжает добавлять эти удивительные улучшения в язык. Что вы хотите улучшить в Swift?