Skip to Content

Async/Await trong Swift

1. Giới thiệu

Swift 5.5+ hỗ trợ async/await cho concurrency, thay thế completion handlers.

2. async Function

func fetchData() async -> String { // Simulate network delay try? await Task.sleep(nanoseconds: 1_000_000_000) return "Data loaded!" } // Gọi async function func loadData() async { let data = await fetchData() print(data) }

3. async throws

enum NetworkError: Error { case invalidURL case serverError } func fetchUser(id: Int) async throws -> User { let url = URL(string: "https://api.example.com/users/\(id)")! let (data, _) = try await URLSession.shared.data(from: url) return try JSONDecoder().decode(User.self, from: data) }

4. Calling Async Code

// Trong async context func example() async { let data = await fetchData() print(data) } // Từ synchronous code Task { let data = await fetchData() print(data) }

5. Parallel Execution với async let

func fetchAllData() async { async let user = fetchUser() async let posts = fetchPosts() async let comments = fetchComments() // Chạy song song let (u, p, c) = await (user, posts, comments) print(u, p, c) }

6. Task Groups

func fetchMultipleUsers(ids: [Int]) async throws -> [User] { try await withThrowingTaskGroup(of: User.self) { group in for id in ids { group.addTask { try await fetchUser(id: id) } } var users: [User] = [] for try await user in group { users.append(user) } return users } }

7. MainActor

@MainActor class ViewModel: ObservableObject { @Published var data: String = "" func loadData() async { let result = await fetchData() data = result // Safe UI update } } // Hoặc inline func updateUI() async { let data = await fetchData() await MainActor.run { // Update UI } }

8. Actors

actor Counter { private var count = 0 func increment() { count += 1 } func getCount() -> Int { count } } let counter = Counter() await counter.increment() print(await counter.getCount())

9. Continuations (Bridge)

// Convert callback to async func fetchDataAsync() async -> String { await withCheckedContinuation { continuation in fetchDataWithCallback { result in continuation.resume(returning: result) } } } // Throwing version func fetchThrowingAsync() async throws -> String { try await withCheckedThrowingContinuation { continuation in fetchWithCallback { result, error in if let error = error { continuation.resume(throwing: error) } else { continuation.resume(returning: result!) } } } }

10. AsyncSequence

func fetchNumbers() -> AsyncStream<Int> { AsyncStream { continuation in for i in 1...5 { continuation.yield(i) } continuation.finish() } } // Usage Task { for await number in fetchNumbers() { print(number) } }

📝 Tóm tắt

  • async đánh dấu async function
  • await chờ kết quả async
  • async let chạy song song
  • Task { } tạo async context
  • @MainActor cho UI updates
  • actor cho thread-safe state
  • Continuations bridge callbacks → async
Last updated on