Объединить: опубликовать sh элементов последовательности с некоторой задержкой - PullRequest
0 голосов
/ 14 апреля 2020

Я новичок в Combine, и я хотел бы получить, казалось бы, простую вещь. Допустим, у меня есть коллекция целых чисел, например:

let myCollection = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Я бы хотел опубликовать sh каждый элемент с задержкой, например, 0,5 секунды.

print 0
wait for 0.5secs
print 1
wait for 0.5secs
and so forth

Я могу легко получить издатель последовательности и напечатать элементы следующим образом:

let publisherCanc = myCollection.publisher.sink { value in
    print(value)
}

Но в этом случае все значения печатаются сразу. Как я могу напечатать значения с задержкой? В Combine есть модификатор .delay, но он не для того, что мне нужно (действительно, .delay задерживает весь поток, а не отдельные элементы). Если я попытаюсь:

let publisherCanc = myCollection.publisher.delay(for: .seconds(0.5), scheduler: RunLoop.main).sink { value in
    print(value)
}

Все, что я получу, это просто «начальная» задержка, тогда элементы будут напечатаны немедленно.

Спасибо за вашу помощь.

1 Ответ

3 голосов
/ 14 апреля 2020

Используя идею из ответа , связанного Александром в комментариях, вы можете создать издателя, который публикует значение каждые 0,5 секунды, используя Timer.publish(every:on:in:), а затем zip, что вместе с помощью Array.publisher, чтобы ваш нижестоящий издатель выдавал значение каждый раз, когда оба ваших издателя выдавали новое значение.

Publishers.Zip берет n-й элемент своего вышестоящего издателя и испускает только тогда, когда оба его восходящих потока достигли n излучаемых значений - следовательно, объединяя издателя, который испускает только 0.5 seconds, с вашим исходным издателем, который испускает все свои значения немедленно, вы задерживаете каждое значение на 0,5 секунды.

let delayPublisher = Timer.publish(every: 0.5, on: .main, in: .default).autoconnect()
let delayedValuesPublisher = Publishers.Zip(myCollection.publisher, delayPublisher)
let subscription = delayedValuesPublisher.sink { print($0.0) }
...