Combine) Time Manipulation Operators


delay(for:scheduler:)


上流publisherでは、間隔を遅延させた時間で値を下流に送信します.delay()オペレータは、パラメータとして、intervalおよび動作のschedulerの遅延をどれだけ受け取るか.autoconnect()が接続されている理由は、Timer.TimerPublisherおよびConnectablePublisherである.
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として受信するポリシーは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:)


debonseは入力終了後にdueTimeを待機し、指定したスケジューラで値を解放します.

throttle(for:scheduler:latest)


throttleの場合、最新値はtrueとfalseに分けられます.
trueの場合、最初の入力値が解放され、dueTimeの後に入力値の最新の入力値が解放されます.
falseの場合、最初に入力した時間からdueTimeまで、dueTimeが終了した後に最後に入力した値を解放します.


timeout(interval:scheduler:options:customError:)


timeout関数は、イベントが間隔の十分な時間内に発生しない限り、customerErrorを解放する.
enum TimeoutError: Error {
  case timedOut
}

let subject = PassthroughSubject<Void, TimeoutError>()


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