SwiftUI Charts Architecture & DataFlow

Swift 中的函数式编程/Task 和 async/await

2025-05-06  本文已影响0人  Tuberose

Swift 中的函数式编程/Task 和 async/await

一、函数式编程风格

在下面的代码中:

let entries = try store
    .getEntries(at: position)
    .compactMap { $0 as? OSLogEntryLog }
    .filter { $0.subsystem == Bundle.main.bundleIdentifier! }
    .filter { $0.date >= date }
    .map { "[\(self.dateFormatter.string(from: $0.date))][\((OSLogLevel(rawValue: $0.level.rawValue) ?? .undefined).title)][\($0.category)] \($0.composedMessage)" }

这种写法属于函数式编程风格,使代码更加简洁、链式操作逻辑清晰,同时利用 Swift 提供的高阶函数实现数据处理。


下面详细解释一下 Task、async 和 await 的区别和使用场景:


二、异步任务 Task 与 async/await 的使用

1. Task 和异步执行


2. async 与 await 的作用


3. 使用场景与结合

下面给出几个常见的 async 函数使用场景及代码示例

// 定义一个 async 函数,使用 URLSession 发起网络请求
func fetchData(from url: URL) async throws -> Data {
    // URLSession 的 data(from:) 方法本身就是 async 的
    let (data, _) = try await URLSession.shared.data(from: url)
    return data
}

// 调用示例
Task {
    do {
        let url = URL(string: "https://api.example.com/data")!
        let data = try await fetchData(from: url)
        print("Received data: \(data.count) bytes")
    } catch {
        print("Network request failed: \(error)")
    }
}

func readFileAsync(at url: URL) async throws -> String {
    // 使用 Swift 的 FileManager 读取文件数据(示例中模拟异步延时操作)
    try await Task.sleep(nanoseconds: 500_000_000)  // 模拟异步耗时操作
    let data = try Data(contentsOf: url)
    guard let content = String(data: data, encoding: .utf8) else {
        throw NSError(domain: "ReadError", code: 0, userInfo: nil)
    }
    return content
}

Task {
    do {
        let fileURL = URL(fileURLWithPath: "/path/to/file.txt")
        let content = try await readFileAsync(at: fileURL)
        print("File content: \(content)")
    } catch {
        print("Failed to read file: \(error)")
    }
}

func queryDatabaseAsync(query: String) async throws -> [String] {
    // 模拟数据库查询,使用 Task.sleep 模拟耗时
    try await Task.sleep(nanoseconds: 1_000_000_000)  // 模拟耗时 1 秒
    // 假设查询结果返回字符串数组
    return ["Result 1", "Result 2", "Result 3"]
}

Task {
    do {
        let results = try await queryDatabaseAsync(query: "SELECT * FROM table")
        print("Database query results: \(results)")
    } catch {
        print("Database query failed: \(error)")
    }
}

func fetchData(from url: URL) async throws -> Data {
    let (data, _) = try await URLSession.shared.data(from: url)
    return data
}

Task {
    do {
        async let data1 = fetchData(from: URL(string: "https://api.example.com/data1")!)
        async let data2 = fetchData(from: URL(string: "https://api.example.com/data2")!)
        // 使用 await 同时等待两个异步请求完成
        let (result1, result2) = try await (data1, data2)
        print("Received data1: \(result1.count) bytes, data2: \(result2.count) bytes")
    } catch {
        print("Error in fetching data: \(error)")
    }
}

在这个例子中,async let 用于并行启动多个异步任务,await (data1, data2) 则同时等待所有任务完成。


5. 总结 async/await 与 Task


总结

通过这种方式,可以避免阻塞主线程,同时又能确保依赖异步操作的代码按照预期顺序执行。


三、Task 和 async/await 以及 GCD/NSOperationQueue

1. Task 和 async/await 的关系

为什么 Task 内部还需要调用 async 函数?


2. 使用场景与优势


3. 现有工具的价值

苹果的目标是逐步引入并推广 Swift Concurrency(Task、async/await)的使用,因为它带来了更好的代码结构、错误处理和并发控制,但 GCD 依然是系统底层的一部分。


4. 结论

上一篇 下一篇

猜你喜欢

热点阅读