一般将闭包结果转换为 Rx?

Convert closure Result to Rx generically?

我有一堆带有结果完成处理程序的函数,我想将它们转换为 RxSwift。

他们遵循这个惯例:

func fetch(id: Int, completion: @escaping (Result<AuthorType, DataError>) -> Void) {...}

我可以使用典型的:

return Observable<AuthorType>.create { on(.next... }

有没有更贴心的通用方式like PromiseKit does:

func fetch() -> Promise<AuthorType> {
return Promise { fetch(completion: [=12=].resolve) }

}

在 RxSwift 中有这样的可能吗?

没有像您要求的开箱即用的构造函数,但创建起来很容易:

extension ObservableType {
    static func createFromResultCallback<E: Error>(_ fn: @escaping (@escaping (Result<Element, E>) -> Void) -> ()) -> Observable<Element> {
        return Observable.create { observer in
            fn { result in
                switch result {
                case .success(let value):
                    observer.onNext(value)
                    observer.onCompleted()
                case .failure(let error):
                    observer.onError(error)
                }
            }
            return Disposables.create()
        }
    }
}

对于您的示例,它可以像这样使用:

func fetch(id: Int) -> Observable<AuthorType> {
    return .createFromResultCallback { fetch(id: id, [=11=]) }
}

如果您有一个只接受回调的函数,例如:

func shortFetch(_ completion: @escaping (Result<AuthorType, DataError>) -> Void)

然后你可以用上面的方法创建一个 Observable :

Observable.createFromResultCallback(shortFetch)

记住 一旦你像这样将函数包装在 Observable 中,行为就会有很大的不同。现在它很冷,这意味着它只有在订阅了 observable 之后才会执行,并且会在每次订阅时执行。这与将立即执行且仅执行一次的 Promise 不同。