Преобразование и объединение потоков
Используйте flatMap, merge, combineLatest и zip.
«Преобразование и объединение потоков» — бесплатный урок Swift Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.
Работа с потоками
В Combine publisher отправляет поток значений с течением времени. Настоящая сила заключается в операторах, которые преобразуют и объединяют эти потоки в новые.
В этом уроке рассматриваются наиболее важные операторы преобразования и объединения: flatMap, merge, combineLatest и zip.
Отображение и flatMap
map преобразует каждое значение в другое значение. flatMap идёт дальше: он преобразует каждое значение в новый publisher и объединяет результаты в единый поток.
Используйте flatMap, когда каждый входной сигнал должен запускать другую асинхронную операцию.
flatMap на практике
Здесь поток идентификаторов пользователей преобразуется в поток сетевых запросов, а затем разворачивается в единый поток пользователей.
userIdPublisher
.flatMap { id in
apiClient.fetchUser(id: id)
}
.sink { user in
print("Loaded", user.name)
}
.store(in: &cancellables)Управление параллелизмом flatMap
По умолчанию flatMap подписывается на все внутренние publisher одновременно. Ограничить параллелизм можно с помощью maxPublishers, чтобы не перегружать сервер.
idsPublisher
.flatMap(maxPublishers: .max(2)) { id in
apiClient.fetchUser(id: id)
}
.sink { print($0) }
.store(in: &cancellables)merge
merge чередует значения из нескольких publisher одного типа в едином потоке, отправляя каждое значение сразу после его поступления.
let combined = buttonTapA
.merge(with: buttonTapB)
combined
.sink { print("A tap from either button") }
.store(in: &cancellables)combineLatest
combineLatest отправляет значение всякий раз, когда его отправляет любой входной publisher, объединяя самые новые значения каждого из них. Этот оператор отлично подходит для проверки форм, где необходимо учитывать сразу несколько полей.
usernamePublisher
.combineLatest(passwordPublisher)
.map { name, pass in
!name.isEmpty && pass.count >= 8
}
.sink { isValid in
print("Form valid:", isValid)
}
.store(in: &cancellables)Поведение combineLatest
Обратите внимание: combineLatest ничего не отправляет, пока каждый входной publisher не выдаст хотя бы одно значение. После этого каждое новое значение любого входа запускает объединённый результат с последними значениями остальных.
zip
zip объединяет значения по индексу: первое значение A с первым значением B, второе со вторым и так далее. Он ждёт, пока обе стороны получат значение на каждой позиции.
let names = ["Ann", "Bob", "Cy"].publisher
let ages = [30, 25, 41].publisher
names
.zip(ages)
.sink { name, age in
print(name, "is", age)
}
.store(in: &cancellables)combineLatest и zip
Эти два оператора легко перепутать:
- combineLatest — срабатывает при любом новом значении и использует самое новое значение каждого входа
- zip — срабатывает только для совпавших по индексу пар
Используйте combineLatest для текущего состояния, а zip — чтобы выровнять параллельные результаты один к одному.
Объединение для параллельной работы
zip особенно полезен, когда независимые запросы выполняются параллельно и нужно дождаться их всех.
fetchProfile
.zip(fetchSettings)
.sink { profile, settings in
print("Both loaded")
}
.store(in: &cancellables)Цепочки операторов
В настоящих конвейерах несколько операторов объединяются в цепочки, чтобы декларативно описывать сложные асинхронные потоки.
searchTextPublisher
.removeDuplicates()
.flatMap { query in
apiClient.search(query)
}
.map { results in
results.prefix(10)
}
.sink { print($0) }
.store(in: &cancellables)Быстрая проверка
Проверьте свои знания об операторах.
Итоги
Вы научились преобразовывать и объединять потоки:
- flatMap — преобразует значение в publisher и разворачивает результат
- merge — чередует потоки одного типа
- combineLatest — использует самое новое значение каждого входа и срабатывает при любом новом значении
- zip — объединяет пары по индексам
Эти операторы позволяют декларативно составлять сложную асинхронную логику.
Часто задаваемые вопросы
Урок «Преобразование и объединение потоков» бесплатный?
Да — полный текст урока «Преобразование и объединение потоков» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.
Чему я научусь в уроке «Преобразование и объединение потоков»?
Используйте flatMap, merge, combineLatest и zip. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Swift Academy?
Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Преобразование и объединение потоков»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Swift Academy?
Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Преобразование и объединение потоков
- Планировщики и потоки выполнения
- Операторы обработки ошибок
- Пользовательские издатели и подписчики