[英]Swift wait for async task
在后台線程中,我們有:
defer {
cleanup()
}
loadData()
if error {
return
}
processData()
DispatchQueue.main.asyncAfter(deadline: delay) { //Delay = now + 0-2 seconds
updateUI()
}
問題是我們要確保 defer cleanUp()
代碼在updateUI()
之后運行。 就目前而言,這不會發生,因為updateUI()
異步運行。
我的想法是在延遲期間休眠/阻塞,而不是異步運行。 一旦updateUI()
完成,這將使 defer cleanUp()
運行。
你怎么能做到這一點? 或者,還有更好的方法?
您可以使用信號量告訴清理任務等待updateUI
完成:
let semaphore = DispatchSemaphore(value: 1)
defer {
semaphore.wait()
cleanup()
}
loadData()
if error {
// If we exit here, the semaphore would have never been used
// and cleanup will run immediately
return
}
processData()
semaphore.wait() // here, we claim the semaphore, making cleanup
// wait until updateUI is done
DispatchQueue.main.asyncAfter(deadline: delay) {
updateUI()
semaphore.signal()
}
意識到我可以改變代碼的結構:
loadData()
if error {
log.error("Error")
} else {
processData()
}
DispatchQueue.main.asyncAfter(deadline: delay) { //Delay = now + 0-2 seconds
updateUI()
cleanup()
}
另一種選擇是使用DispatchGroup()
:
func doWork() {
let group = DispatchGroup()
group.enter() //Enter #1
loadData { result in
switch (result) {
case .success(_):
group.enter()//Enter #2
processData { group.leave()//Leave #2 }
case .failure(let error):
//Do something nice with the error
print(error)
}
group.leave()//Leave #1
}
//All the code inside this block will be executed on the mainThread when all tasks will be finished.
group.notify(queue: .main) { [weak self] in
guard let strongSelf = self else { return }
strongSelf.updateUI()
strongSelf.cleanup()
}
}
private func updateUI() {
//All your stuff
}
private func cleanup() {
//All your stuff
}
private func loadData(completion: (Result<(), Error>) -> ()) {
//All your stuff
if error {
completion(.failure(error))
}
else {
completion(.success(()))
}
}
private func processData(completion: () -> ()) {
//All your stuff
completion()
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.