Last active
February 25, 2021 22:54
-
-
Save manas-sharma-1683/51c61440ccdc85c93b0a1db35c7b2f7d to your computer and use it in GitHub Desktop.
How to wait for two callbacks in swift.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* | |
* 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