Async let является частью среды параллелизма Swift и позволяет асинхронно создавать константы. Платформа параллелизма представила концепцию асинхронного ожидания, которая приводит к структурированному параллелизму и более читаемому коду для асинхронных методов.
Как использовать async let
При объяснении того, как использовать async let, важнее знать, когда использовать async let. Я собираюсь показать вам примеры кода, в которых используется асинхронный метод для загрузки случайного изображения:
func loadImage(index: Int) async -> UIImage {
let imageURL = URL(string: "https://picsum.photos/200/300")!
let request = URLRequest(url: imageURL)
let (data, _) = try! await URLSession.shared.data(for: request, delegate: nil)
print("Finished loading image \(index)")
return UIImage(data: data)!
}
Без async let мы бы назвали этот метод следующим образом:
func loadImages() {
Task {
let firstImage = await loadImage(index: 1)
let secondImage = await loadImage(index: 2)
let thirdImage = await loadImage(index: 3)
let images = [firstImage, secondImage, thirdImage]
}
}
Таким образом, мы говорим нашему приложению ждать возврата первого изображения, пока оно не сможет продолжить получение второго изображения. Все изображения загружаются последовательно, и мы всегда будем видеть в консоли вывод следующего порядка:
Finished loading image 1
Finished loading image 2
Finished loading image 3
Поначалу это может выглядеть просто отлично. Наши изображения загружаются асинхронно, и в итоге мы получаем массив изображений, которые можно использовать для отображения в представлении. Однако было бы намного эффективнее загружать изображения параллельно и использовать доступные системные ресурсы.
Здесь на помощь приходит async let:
func loadImages() {
Task {
async let firstImage = loadImage(index: 1)
async let secondImage = loadImage(index: 2)
async let thirdImage = loadImage(index: 3)
let images = await [firstImage, secondImage, thirdImage]
}
}
Следует отметить несколько важных частей:
- Наш массив изображений теперь должен быть определен с помощью ключевого слова await, так как мы имеем дело с асинхронными константами.
- Выполнение начнется, как только мы определим async let
Последний пункт в основном означает, что одно из изображений уже может быть загружено вашим приложением еще до того, как оно будет ожидаться в массиве. В данном случае это чисто теоретически, так как вполне вероятно, что ваш код выполняется быстрее, чем загрузка изображения.
Запуск этого кода покажет другой вывод в консоли:
Finished loading image 3
Finished loading image 1
Finished loading image 2
Каждый раз, когда вы запускаете приложение, он может меняться, поскольку порядок зависит от времени запроса, необходимого для загрузки изображения.
Когда использовать async let?
Async let следует использовать, когда вам не нужен результат асинхронного метода до конца вашего кода. Вместо этого вы должны использовать await, если какие-либо следующие строки в вашем коде зависят от результата асинхронного метода.
Могу ли я объявить async let на верхнем уровне?
Вы можете задаться вопросом, работает ли следующий код в Swift:
final class ContentViewModel: ObservableObject {
async let firstImage = await loadImage(index: 1)
// .. rest of your code
}
К сожалению, компилятор выдаст ошибку:
«async let» можно использовать только в локальных объявлениях.
Другими словами, вы можете использовать async let только для локальных объявлений внутри методов.