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 functionawaitchờ kết quả asyncasync letchạy song songTask { }tạo async context@MainActorcho UI updatesactorcho thread-safe state- Continuations bridge callbacks → async
Last updated on
Swift