RxSwift вызывает простую функцию в планировщике

#ios #swift #rx-swift

#iOS #swift #rx-swift

Вопрос:

У меня есть простая нереактивная функция, которую я хотел бы запустить на SerialDispatchQueueScheduler . Метод ничего не возвращает, и я не требую, чтобы он выдавал какие-либо события, но его нужно запускать в планировщике

 func deleteDataOf(_ personId: Int, on scheduler: SerialDispatchQueueScheduler) {
    //Run the method body on scheduler
    try? removeItem(at: getDirectoryURL(personId: personId))
}
 

Ответ №1:

Самое простое решение — поместить ваш побочный эффект в .do(onNext:) .subscribe(onNext:) оператор или, который вызывается в рассматриваемом планировщике. Таким образом, это часть наблюдаемой цепочки.

Следующий самый простой способ — запланировать операцию в планировщике:

 func deleteDataOf(_ personId: Int, on scheduler: SchedulerType) -> Disposable {
    scheduler.schedule(()) {
        try? removeItem(at: getDirectoryURL(personId: personId))
        return Disposables.create()
    }
}
 

Обратите внимание, что он возвращает одноразовый для возможной отмены.

Я замечаю, что ваш побочный эффект вызывает сбои, что для меня подразумевает, что вы потенциально заинтересованы в ошибках. Возможно, завершаемый вариант был бы лучшей идеей, но тогда вам пришлось бы подписаться на результат.

Что-то вроде этого:

 func deleteDataOf(_ personId: Int) -> Completable {
    Completable.deferred {
        do {
            try removeItem(at: getDirectoryURL(personId: personId))
            return .empty()
        }
        catch {
            return .error(error)
        }
    }
}

func deleteDataOf(_ personId: Int, on scheduler: SchedulerType) {
    _ = deleteDataOf(personId)
        .subscribeOn(scheduler)
        .subscribe(onError: { print("there was an error", $0) })
}
 

Ответ №2:

Возможно, есть способы получше, но вы можете сделать что-то вроде этого:

 func runOnScheduler<I>(
  scheduler: SerialDispatchQueueScheduler,
  f: @escaping (I) -> Void,
  param: I
) {
  Observable.just(param)
    .observeOn(scheduler)
    .subscribe(onNext: f)
}

func deleteDataOf(_ personId: Int) {
  print(Thread.isMainThread)
}

runOnScheduler(
  scheduler: SerialDispatchQueueScheduler(qos: .background),
  f: deleteDataOf,
  param: 1
)

// false