Combine) Time Manipulation Operators

delay(for:scheduler:)

upstream publisher에서 interval만큼 delay된 시간에 값을 downstream으로 emit한다.
delay() operator는 얼마만큼의 delay를 줄지에 대한 interval과 동작할 scheduler를 인자로 받는다.
autoconnect()로 연결해주는 이유는 Timer.TimerPublisherConnectablePublisher이기 때문이다.

let valuesPerSecond = 1.0
let delayInSeconds = 1.5

let sourcePublisher = PassthroughSubject<Date, Never>()

let delayedPublisher =
sourcePublisher.delay(for: .seconds(delayInSeconds), scheduler:
DispatchQueue.main)

let subscription = Timer
  .publish(every: 1.0 / valuesPerSecond, on: .main, in: .common)
  .autoconnect()
  .subscribe(sourcePublisher)

collect(strategy:options:)

collect()함수는 지정된 시간 혹은 count를 가지고 수집한 값을 방출한다. 특정 기간의 평균을 구할 때 사용되곤 한다. 앞서 설명했던 count만 가지고 collect하는 함수와 마찬가지로 많은 메모리를 소유할 수 있기에 사용에 주의해야한다.

let collectTimeStride = 4
let sourcePublisher = PassthroughSubject<Date, Never>()

let collectedPublisher = sourcePublisher
  .collect(.byTime(DispatchQueue.main, .seconds(collectTimeStride)))
  .flatMap { dates in dates.publisher }

let collectedPublisher2 = sourcePublisher
  .collect(.byTimeOrCount(DispatchQueue.main, .seconds(collectTimeStride), 2))
  .flatMap { dates in dates.publisher }

let subscription = Timer
  .publish(every: 1.0, on: .main, in: .common)
  .autoconnect()
  .subscribe(sourcePublisher)

parameter로 받는 strategy는 enum으로 다음과 같다.

public enum TimeGroupingStrategy<Context> where Context : Scheduler {

        /// A grouping that collects and periodically publishes items.
        case byTime(Context, Context.SchedulerTimeType.Stride)

        /// A grouping that collects and publishes items periodically or when a buffer reaches a maximum size.
        case byTimeOrCount(Context, Context.SchedulerTimeType.Stride, Int)
    }

debounce(for:scheduler:)

debounce는 입력이 끝난 뒤에 dueTime동안 기다린 뒤 지정된 scheduler를 통해 값을 방출 시킨다.

throttle(for:scheduler:latest)

throttle의 경우 latest가 true일 때랑 false일 때로 나뉜다.
true일 경우 처음 들어온 값을 방출한 뒤, dueTime뒤에 입력 값들 중 latest하게 들어온 값을 방출한다.
false일 경우 처음 입력이 들어온 시간부터 dueTime까지 기다리다가 dueTime이 끝나면 lastest하게 들어온 값을 방출한다.

timeout(interval:scheduler:options:customError:)

timeout 함수는 interval 만큼의 시간동안 이벤트가 발생하지 않으면 customError를 방출한다.

enum TimeoutError: Error {
  case timedOut
}

let subject = PassthroughSubject<Void, TimeoutError>()


let timedOutSubject = subject.timeout(.seconds(5), 
                                      scheduler: DispatchQueue.main,
                                      customError: { .timedOut })

좋은 웹페이지 즐겨찾기