如何在Swift上同步或进行可观察的等待?

时间:2019-01-15 20:46:23

标签: swift observable rx-swift reactive-cocoa

因此,我具有此登录功能,根据登录的成功情况,我想向.xib控制器返回一个布尔值,在该.xib控制器中必须对其进行一些修改。

 func login(cpf: String) -> Bool {
    let url = URL(string: AccessibilityDataAccessProvider.kLoginURL)
    let params = ["username": String.init(describing: cpf)]

    var success = false

    dataAccessProvider.postSimpleResponse(url: url!, params: params)
        .subscribe(onNext: { (userToken) in
            let userData = UserDefaults.standard
            userData.set(userToken, forKey: AccessibilityDataAccessProvider.userTokenKey)
            userData.synchronize()
            success = true
    }, onError: { (error) in
        print("Login Error: \(error)")
    }).disposed(by: disposeBag)

    return success
}

postSimpleResponse()方法的返回值是 Any?类型的 Observable

问题是,在订阅中将 success 布尔变量设置为true之前,我的 login()方法正在返回。

我该如何解决?

2 个答案:

答案 0 :(得分:0)

您可以将Observable映射到Bool的Observable(尽管此处Bool不是必需的,但是您可以使用Void),然后从{{1 }} 方法。

赞:

Observable

然后观察它:

login

答案 1 :(得分:0)

正如之前所说:

<块引用>

Rx 的全部意义在于您使用 Observables 为异步任务建模。

但是如果你真的需要让 observable 同步(等到 onNext,或者 onCompleted),你可以使用 DispatchGroup (monitor)。

您的代码应如下所示:

func login(cpf: String) -> Bool {
    let url = URL(string: AccessibilityDataAccessProvider.kLoginURL)
    let params = ["username": String.init(describing: cpf)]

    var result = false

    let group = DispatchGroup()
    group.enter()

    let subscription = dataAccessProvider.postSimpleResponse(url: url!, params: params)
        .subscribe(onNext: {
            let userData = UserDefaults.standard
            userData.set(userToken, forKey: AccessibilityDataAccessProvider.userTokenKey)

            result = true
            group.leave()
        }, onError: { _ in 
            group.leave()
        })

    group.wait() // wait till leave() method called
    subscription.dispose()

    return result
}

你应该记住这种方法会阻塞当前线程,直到异步代码的执行完成。因此,它并不完美,但有时可能是必要的。