Swift 中的async和await

异步编程是指程序在执行任务时,不需要等待任务完成才能继续执行其他任务。传统的同步编程方式会导致程序等待某个操作完成(比如网络请求、磁盘读写等),直到任务完成后才会继续执行,可能会造成性能瓶颈。异步编程允许程序在等待某个操作时去执行其他任务,从而提高效率。

asyncawait 是 Swift 5.5 引入的用于处理异步编程的关键字,它们使得处理异步任务变得更加简单和直观。它们提供了一种新的方式来管理异步操作,相比传统的回调函数或闭包,async/await 更接近同步代码的写法,让代码更加易读和可维护。

一、asyncawait

  • async : 用于标记一个函数为异步函数。异步函数会返回一个 Task 类型,可以在执行时暂停,直到结果准备好。
  • await: 用于暂停函数的执行,直到异步操作完成并返回结果。

1、标记异步函数

使用 async 关键字来定义一个异步函数,表示这个函数包含异步操作,并且可能需要一些时间来执行。

Swift 复制代码
func handleData() async ->String{
        
        // 模拟网络请求,慢处理等
        
        return "handle data"
    }

handleData()是一个异步函数,它返回一个字符串。函数内部的操作可能会是一个耗时操作,虽然这里没有具体的异步代码,但它表示这段代码可以用异步方式进行处理。

2、 调用异步函数

调用一个异步函数,必须在一个异步上下文中使用 await 关键字。await 会暂停当前的代码执行,直到异步函数返回结果。

Swift 复制代码
/// 去调用异步任务
    func callAsync() async{
        /// 等待异常函数返回结果
        let result = await handleData()
        print(result)
    }

    func handleData() async ->String{
        // 模拟网络请求,慢处理等
        return "handle data"
    }

3 异步任务的创建

使用 Task 来创建异步任务。Task 允许你在异步上下文之外执行异步代码。

Swift 复制代码
override func viewDidLoad() {
        super.viewDidLoad()
        print("1")
        Task {
            /// 等待异常函数返回结果
            let result = await handleData()
            print(result)
        }
        print("2")
    }

    func handleData() async ->String{
        // 模拟网络请求,慢处理等
        return "handle data"
    }
    
    // 打印信息 1 、 2 、 handle data

Task 是一个异步任务,它会自动创建一个新的异步上下文来执行异步代码。当你需要在不直接处于异步函数内部的地方执行异步代码时。

二、asyncawait 与传统的闭包回调对比

传统的异步编程中,我们可能会使用闭包来处理异步操作的回调

Swift 复制代码
override func viewDidLoad() {
        super.viewDidLoad()
        
        handleData { data in
            print(data)
        }
       
    }
    func handleData(completion: @escaping(String) -> Void){
        DispatchQueue.main.async {
            let data = "handle data"
            completion(data)
        }
    }

使用 asyncawait 后,你可以这样写

Swift 复制代码
 override func viewDidLoad() {
         super.viewDidLoad()
         Task {
             /// 等待异常函数返回结果
             let result = await handleData()
             print(result)
         }
     }

     func handleData() async ->String{
         // 模拟网络请求,慢处理等
         return "handle data"
     }

相比使用闭包,asyncawait 更加简洁、直观。

三、错误处理

异步函数中,错误处理通常使用 do-catch 语句来处理。你可以在异步函数中抛出错误,并使用 await 来捕获和处理它们

Swift 复制代码
enum jlDataError: Error{
    case invalidData
}

 class ViewController: UIViewController {

     override func viewDidLoad() {
         super.viewDidLoad()
         Task {
             do {
                 let result = try await handleData()
                 print(result)
             } catch{
                 print("Error:\(error)")
             }
             
         }

     }

     func handleData() async throws ->String{
         
         let success = false
         if success == false{
             throw jlDataError.invalidData
         }
         // 模拟网络请求,慢处理等
         return "handle data"
     }
     
 }

上述代码中,handleData() 可能会抛出 DataError.invalidData 错误,调用它时需要使用 try await 来捕获和处理错误。

四、 并发执行多个异步任务

可以使用 async let 来并行执行多个异步任务,并且在最后获取它们的结果。这是一个非常强大的功能,尤其是当你需要同时处理多个异步操作时。

Swift 复制代码
override func viewDidLoad() {
         super.viewDidLoad()
         Task {
             // 异步并发任务
             async let handleData1 = handleData1()
             // 异步并发任务
             async let handleData2 = handleData2()
             // 等待结果
             let r1 = await handleData1
             let r2 = await handleData2
             print(r1,r2)
             
         }

     }

     func handleData1() async  ->String{
        
         // 模拟网络请求,慢处理等
         return "handle data1"
     }
     
     func handleData2() async  ->String{
        
         // 模拟网络请求,慢处理等
         return "handle data2"
     }

在上面的代码中,handleData1handleData2 会并行执行,最终我们使用 await 来获取它们的结果。

总结

asyncawait 是处理异步操作的核心工具,它们通过提供一种类似同步代码的结构,使得异步编程更加简单和清晰。使用这些特性,你可以:

  • 简化代码,使其更加易读和维护。
  • 避免回调地狱(callback hell)和嵌套的闭包。
  • 更容易进行错误处理。
  • 使并发执行变得简单,减少手动管理异步任务的复杂度。
相关推荐
Zender Han1 小时前
Flutter 中 AbsorbPointer 与 IgnorePointer 的区别与使用场景详解
android·flutter·ios
Digitally3 小时前
3种简单方法备份 iPhone 短信
ios·iphone
2501_915921433 小时前
Flutter App 到底该怎么测试?如何在 iOS 上进行测试
android·flutter·ios·小程序·uni-app·cocoa·iphone
二流小码农3 小时前
鸿蒙开发:一个底部的曲线导航
android·ios·harmonyos
2501_915909063 小时前
如何在 Windows 上上架 iOS App,分析上架流程哪些是不用mac的
android·macos·ios·小程序·uni-app·iphone·webview
TheNextByte14 小时前
如何用 5 种简单方法抹掉 iPhone 上的密码?
ios·iphone
2501_915921434 小时前
分析 iOS 描述文件创建与管理中常见的问题
android·ios·小程序·https·uni-app·iphone·webview
东坡肘子4 小时前
Swift、SwiftUI 与 SwiftData:走向成熟的 2025 -- 肘子的 Swift 周报 #116
人工智能·swiftui·swift
大熊猫侯佩16 小时前
Swift 6.2 列传(第十三篇):香香公主的“倾城之恋”与优先级飞升
swift·编程语言·apple