您如何以简洁和可读的方式顺序链接可观察对象

时间:2019-01-23 16:01:36

标签: swift promise rx-swift

我是RXSwift的新手,我已经开始研究如何执行Promise之类的函数链接。

我认为使用Flatmap的方法是正确的,但是我的实现很难阅读,因此我怀疑有更好的方法来实现它。

我在这里拥有的东西似乎行得通,但我想知道如果在链中添加另外3个或函数会是什么样子。

在这里我声明“承诺链”(难以阅读)

LOGIN().flatMap{ (stuff) -> Observable<Int> in
    return API(webSiteData: stuff).flatMap
    { (username) -> Observable<ProfileResult> in
    return accessProfile(userDisplayName: username) }
    }.subscribe(onNext: { event in
        print("The Chain Completed")
        print(event)
    }, onError:{ error in
         print("An error in the chain occurred")
    })

这是我链接的3个示例函数

struct apicreds
{
    let websocket:String
    let token:String
}
typealias APIResult = String
typealias ProfileResult = Int

// FUNCTION 1
func LOGIN() -> Observable<apicreds> {

    return Observable.create { observer in
        print("IN LOGIn")
        observer.onNext(apicreds(websocket: "the web socket", token: "the token"))
        observer.on(.completed)
        return Disposables.create()
    }
}
// FUNCTION 2
func API(webSiteData: apicreds) -> Observable<APIResult> {

    return Observable.create { observer in
        print("IN API")
        print (webSiteData)
       // observer.onError(myerror.anError)
        observer.on(.next("This is the user name")) // assiging "1" just as an example, you may ignore
        observer.on(.completed)
        return Disposables.create()
    }

}
//FUNCTION 3
func accessProfile(userDisplayName:String)  -> Observable<ProfileResult>
{
    return Observable.create { observer in

        // Place your second server access code
        print("IN Profile")
        print (userDisplayName)

        observer.on(.next(200)) // 200 response from profile call
        observer.on(.completed)
        return Disposables.create()
    }
}

3 个答案:

答案 0 :(得分:3)

这是我们在链接操作时遇到的一个非常普遍的问题。作为一个初学者,我在项目中也使用RxSwift编写了类似的代码。有两个方面的改进-  1.重构代码以删除嵌套的flatMaps  2.采用不同的格式,以使序列更容易理解

LOGIN()
    .flatMap{ (stuff) -> Observable<APIResult> in
        return API(webSiteData: stuff)
    }.flatMap{ (username) -> Observable<ProfileResult> in
        return accessProfile(userDisplayName: username) 
    }.subscribe(onNext: { event in
        print("The Chain Completed")
        print(event)
    }, onError:{ error in
        print("An error in the chain occurred")
    })

答案 1 :(得分:2)

  1. 除了嵌套flatMap和代码格式外,您还可以省略return和显式返回类型:
LOGIN()
    .flatMap { webSiteData in API(webSiteData: webSiteData) }

参数名称

LOGIN()
    .flatMap { API(webSiteData: $0) }

甚至在适当的地方完全删除参数:

LOGIN()
    .flatMap(API)
    .flatMap(accessProfile)
    .subscribe(
        onNext: { event in
            print(event)
        }, onError:{ error in
            print(error)
        }
    )
  1. 仅供参考,这里有Observable.just方法会很方便:
struct ApiCredentials {
    let websocket: String
    let token: String
}

func observeCredentials() -> Observable<ApiCredentials> {
    let credentials = ApiCredentials(websocket: "the web socket", token: "the token")
    return Observable.just(credentials)
}
  1. 尝试遵循官方Swift API Guidelines,以使您的代码更具可读性。

答案 2 :(得分:1)

您还可以使用无点样式,只需将函数引用传递给flatMap

LOGIN()
    .flatMap(API)
    .flatMap(accessProfile)
    .subscribe(onNext: { event in
        print("The Chain Completed")
        print(event)
    }, onError:{ error in
        print("An error in the chain occurred")
    })