I have two asynchronous functions. I need to run second function based on first's output and run third function after second is complete. I did it like this. Is it correct way to handle serialization? And how to handle weak self reference?
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
function1() // async completion contains leave()
dispatchGroup.notify(queue: DispatchQueue.main) { [weak self] in
guard let strongSelf = self else {return}
strongSelf.dispatchGroup.enter()
strongSelf.function2() // Also async, dependent on the result of function1. contains leave()
strongSelf.dispatchGroup.notify(queue: DispatchQueue.main) {
strongSelf????.function3()
print("results of function1 and function2")
// I must wait to finish first two tasks in order, in other words serial queue
}
}
class SomeAsyncType {
typealias SomeResultType = String
func async(_ someDate: Any, completion: @escaping (SomeResultType) -> Void) {
self.asyncfunctionA(someDate, completion: completion)
}
private func asyncfunctionA(_ someDate: Any, completion: @escaping (SomeResultType) -> Void) {
DispatchQueue.main.async { [weak self] in
sleep(1)
print("ResultA")
self?.asyncfunctionB("ResultA", completion: completion)
}
}
private func asyncfunctionB(_ someDate: Any, completion: @escaping (SomeResultType) -> Void) {
DispatchQueue.main.async { [weak self] in
sleep(2)
print("ResultB")
self?.asyncfunctionC("ResultB", completion: completion)
}
}
private func asyncfunctionC(_ someDate: Any, completion: @escaping (SomeResultType) -> Void) {
DispatchQueue.main.async {
sleep(3)
print("ResultC")
completion("🙈🙊🙉")
print("All completed")
}
}
}
let test = SomeAsyncType() // hold reference
test.async("noDate") { result in
print(result)
}
ResultA
ResultB
ResultC
🙈🙊🙉
All completed
This is new scope then you can use [weak self]
again
dispatchGroup.notify(queue: DispatchQueue.main) { [weak self] in
guard let strongSelf = self else {return}
strongSelf.dispatchGroup.enter()
strongSelf.function2() // Also async, dependent on the result of function1. contains leave()
strongSelf.dispatchGroup.notify(queue: DispatchQueue.main) { [weak self] in
guard let strongSelf = self else {return}
strongSelf.function3()
print("results of function1 and function2")
}
}