То, что мешает вам сжать произвольное количество издателей, - это очень прискорбный факт, что Apple решила сделать вывод операторов zip равным кортежу . Кортежи чрезвычайно негибки и ограничены в своих возможностях. Вы не можете иметь кортеж, скажем, из десяти элементов; и вы даже не можете добавить элемент в кортеж, потому что это заставляет вас получать другой тип. Поэтому нам нужен новый оператор, который выполняет ту же работу, что и zip
, но выдает более мощный и гибкий результат, например массив.
И мы можем его создать! К счастью, сам оператор zip
имеет параметр transform
, который позволяет нам указать, какой тип вывода мы хотим.
Хорошо, так что, чтобы проиллюстрировать это, я заархивирую десять издателей все вместе. Во-первых, я сделаю массив из десяти издателей; они будут просто издателями, но этого достаточно, чтобы доказать, что, чтобы доказать, что я не обманываю, я добавлю произвольную задержку к каждому из них:
let justs = (1...10).map {
Just($0)
.delay(for: .seconds(Int.random(in:1...3)), scheduler: DispatchQueue.main)
.eraseToAnyPublisher() }
Хорошо, теперь я У нас есть множество издателей, и я соберу их вместе в al oop:
let result = justs.dropFirst().reduce(into: AnyPublisher(justs[0].map{[$0]})) {
res, just in
res = res.zip(just) {
i1, i2 -> [Int] in
return i1 + [i2]
}.eraseToAnyPublisher()
}
Обратите внимание на завершающее замыкание после оператора zip
! Это гарантирует, что мой вывод будет Array<Int>
вместо кортежа. В отличие от кортежа, мне разрешено создавать массив любого размера, просто добавляя элементы каждый раз через l oop.
Хорошо, теперь result
теперь является Zip-издателем, объединяющим десять издателей . Чтобы доказать это, я просто прикреплю к нему подписчика и напечатаю вывод:
result.sink {print($0)}.store(in: &self.storage)
Запускаем код. Наступает душераздирающая пауза - правильно, потому что каждый из этих издателей Just имеет различную случайную задержку, и правило zip состоит в том, что им all необходимо опубликовать sh, прежде чем мы получим какой-либо вывод. Все они делают, рано или поздно, и вывод появляется в консоли:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Точно правильный ответ! Я доказал, что на самом деле я объединил десять издателей, чтобы получить выходные данные, состоящие из одного вклада каждого из них.
Сжатие произвольного числа издателей задач с данными (или что вы используете) ничем не отличается.
(По вопросам, связанным с тем, как я сериализую произвольное число издателей задач с данными, см. Объединение платформы сериализации asyn c Операции .)