// *** before: ***
func fetchUserOld(id: Int, completion: @escaping (User?, Error?) -> Void) { }
func fetchPostsOld(user: User, completion: @escaping ([Post]?, Error?) ->
Void) { }
fetchUserOld(id: 1) { user, error in
guard let user = user else { return } // every branch must remember
fetchPostsOld(user: user) { posts, error in // to call the completion,
guard let posts = posts else { return } // and one forgotten return
print(user, posts) // hangs the screen forever
}
}
// *** in version 5.5: ***
func fetchUser(id: Int) async throws -> User { User() }
func fetchPosts(user: User) async throws -> [Post] { [] }
func load() async throws {
let user = try await fetchUser(id: 1)
let posts = try await fetchPosts(user: user)
print(user, posts)
}
// await marks the place where the function may be suspended: the thread is
// given away and taken back later, and the code still reads top to bottom.
// Errors travel by the usual throws, and the result by the usual return