Skip to content

Instantly share code, notes, and snippets.

@manas-sharma-1683
Last active February 25, 2021 22:54
Show Gist options
  • Save manas-sharma-1683/51c61440ccdc85c93b0a1db35c7b2f7d to your computer and use it in GitHub Desktop.
Save manas-sharma-1683/51c61440ccdc85c93b0a1db35c7b2f7d to your computer and use it in GitHub Desktop.
How to wait for two callbacks in swift.
/*
*
* I recommend using RxSwift, Combine or PromiseKit for this kind of flow.
*
*/
import UIKit
import Foundation
func wait<A,B>(_ blockA: @escaping (@escaping (Result<A,Error>) -> Void) -> Void,
_ blockB: @escaping (@escaping (Result<B,Error>) -> Void) -> Void,
then execute: @escaping (Result<(A,B),Error>) -> Void) {
var resultA: A?
var resultB: B?
var firstError: Error?
let group = DispatchGroup()
group.enter()
blockA { (result) in
switch result {
case .success(let payload):
resultA = payload
case .failure(let error):
firstError = error
}
group.leave()
}
group.enter()
blockB { (result) in
switch result {
case .success(let payload):
resultB = payload
case .failure(let error):
firstError = error
}
group.leave()
}
group.notify(queue: .main) {
if let error = firstError {
execute(.failure(error))
} else if let resultA = resultA,
let resultB = resultB {
execute(.success((resultA, resultB)))
}
}
}
func getUsersCount(then execute: @escaping (Result<Int, Error>) -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
execute(.success(10))
}
}
func getUsername(then execute: @escaping (Result<String, Error>) -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) {
execute(.success("@manasshr"))
}
}
wait(getUsersCount, getUsername) { (result) in
switch result {
case .success((let result1, let result2)):
print(result1, result2)
case .failure(let error):
print(error)
}
}
/*
*
* Methods that have paramaters other than the callback cannot be used which makes this approach very inflexible.
* For example:
*
* func getPost(id: Int, then execute: @escaping (Result<String, Error>) -> Void) {}
*
* // error here
* wait(getUsersCount, getPost(id: 20, then:) ) { (_) in }
*
*
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment