如何在 Swift 上同步或让 Observable 等待?
How to Synchronize or make an Observable wait on Swift?
所以,我有这个登录功能,我想 return 一个布尔值到我的 .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() 方法的 return 是 Observable 类型 Any?.
问题是,我的 login() 方法在 success 布尔变量设置为 true 之前 returning在订阅中。
我该如何解决这个问题?
你可以将 Observable 映射到一个 Bool
observable(虽然这里 Bool
不是必需的,你可以只使用 Void
),并且 return Observable
来自 login
方法。
像这样:
func login(cpf: String) -> Observable<Bool> {
let url = URL(string: AccessibilityDataAccessProvider.kLoginURL)
let params = ["username": String.init(describing: cpf)]
return dataAccessProvider.postSimpleResponse(url: url!, params: params)
.do(onNext: {
let userData = UserDefaults.standard
userData.set(userToken, forKey: AccessibilityDataAccessProvider.userTokenKey)
})
.map { _ in
return true
}
}
然后在上面观察:
login(cpf: "data").subscribe(onNext: { _ in
// Success
}, onError: { _ in
// Failure
}).disposed(by: disposeBag)
如前所述:
The whole point of Rx is that you model asynchronous tasks with 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
}
你应该记住,这种方法会阻塞当前线程,直到异步代码执行完毕。因此,它并不完美,但有时可能是必要的。
所以,我有这个登录功能,我想 return 一个布尔值到我的 .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() 方法的 return 是 Observable 类型 Any?.
问题是,我的 login() 方法在 success 布尔变量设置为 true 之前 returning在订阅中。
我该如何解决这个问题?
你可以将 Observable 映射到一个 Bool
observable(虽然这里 Bool
不是必需的,你可以只使用 Void
),并且 return Observable
来自 login
方法。
像这样:
func login(cpf: String) -> Observable<Bool> {
let url = URL(string: AccessibilityDataAccessProvider.kLoginURL)
let params = ["username": String.init(describing: cpf)]
return dataAccessProvider.postSimpleResponse(url: url!, params: params)
.do(onNext: {
let userData = UserDefaults.standard
userData.set(userToken, forKey: AccessibilityDataAccessProvider.userTokenKey)
})
.map { _ in
return true
}
}
然后在上面观察:
login(cpf: "data").subscribe(onNext: { _ in
// Success
}, onError: { _ in
// Failure
}).disposed(by: disposeBag)
如前所述:
The whole point of Rx is that you model asynchronous tasks with 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
}
你应该记住,这种方法会阻塞当前线程,直到异步代码执行完毕。因此,它并不完美,但有时可能是必要的。