You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

async/await对比URLSession:新手困惑的实际优势解析

Async/Await 相较于嵌套Completion的核心优势详解

一、串行请求场景下Async/Await的额外优势

先看你当前的嵌套Completion实现:

public func example1() {
    
    NetworkingModels.shared.fetchFirstSet(completion: { events in
        switch events {
            
        case .success:
            example2()
            completion(.success(()))
        case .error(let error):
            Logger.logError(error)
        }
    })
}


public func example2() {
    
    NetworkingModels.shared.fetchSecondSet(completion: { events in
        switch events {
            
        case .success:
            example3()
            completion(.success(()))
        case .error(let error):
            Logger.logError(error)
        }
    })
}


public func example3() {
    
    NetworkingModels.shared.fetchThirdSet(completion: { events in
        switch events {
            
        case .success:
            completion(.success(()))
        case .error(let error):
            Logger.logError(error)
        }
    })
}

对比Async/Await的串行写法:

Task {
   do {
      try await example1()
      try await example2()
      try await example3()
   } catch {
      Logger.logError(error)
   }
}

除了代码简洁,还有这些关键优势:

  • 错误处理更集中统一:嵌套写法里错误分散在每个闭包中,容易遗漏;Async/Await可以用do-catch一次性捕获所有请求的错误,不用在每个回调里重复写错误处理逻辑。
  • 避免回调地狱的扩展性问题:如果后续要新增第4、5个请求,嵌套写法会继续加深代码层级,维护难度陡增;Async/Await只要加一行await example4(),始终保持扁平结构。
  • 线程调度自动处理:原来的Completion写法需要手动调用DispatchQueue.main.async切回主线程,Async/Await会自动在调用的上下文恢复执行,减少线程相关的bug。
  • 流程控制更直观:可以直接把异步请求的结果赋值给变量(比如let firstData = try await example1()),后续逻辑不用嵌套在闭包里,线性的代码逻辑更符合人类思考习惯。

二、URLSession的Completion写法转Async/Await的优势

先看你当前的getHTML实现:

public func getHTML(url: String, completion: @escaping Result<String>.Completion) {
    
    guard let url = URL(string: url) else { return }
    
    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    
    let sessionConfiguration = URLSessionConfiguration.default
    
     if let userAgent = Settings.Generic.userAgent {
        sessionConfiguration.httpAdditionalHeaders = ["User-Agent": userAgent]
    }
        
    let session = URLSession.init(configuration: sessionConfiguration)

    session.dataTask(with: request) {data, response, error in
        
        if error != nil {
            DispatchQueue.main.async {
                completion(.error(HTMLError.failedToExtractHTML))
            }
        }
        
        if let data = data {
            if let html = String(data: data, encoding: .utf8) {
                completion(.success((html)))
            }
        }
    }.resume()
}

转成Async/Await后的写法示例:

public func getHTML(url: String) async throws -> String {
    guard let url = URL(string: url) else {
        throw HTMLError.invalidURL
    }
    
    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    
    let sessionConfiguration = URLSessionConfiguration.default
    if let userAgent = Settings.Generic.userAgent {
        sessionConfiguration.httpAdditionalHeaders = ["User-Agent": userAgent]
    }
    
    let session = URLSession(configuration: sessionConfiguration)
    let (data, response) = try await session.data(for: request)
    
    // 新增响应状态码校验,避免无效数据
    guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else {
        throw HTMLError.invalidResponse
    }
    
    guard let html = String(data: data, encoding: .utf8) else {
        throw HTMLError.failedToExtractHTML
    }
    
    return html
}

关于你的疑问,具体优势如下:

  • 速度不会直接提升:底层还是依赖URLSession的网络请求,耗时主要由网络环境和服务端响应决定。但Async/Await可以减少手动线程切换的冗余开销,让代码执行流程更高效。
  • 可靠性显著增强:
    • 避免静默失败:原来的写法中,如果数据存在但转String失败,没有调用completion,会导致调用方永远等待;Async/Await用throws强制抛出错误,必须处理,不会出现这种无响应的情况。
    • 更严谨的校验:可以轻松新增响应状态码校验等逻辑,原来的写法容易忽略这类边界情况。
    • 降低内存泄漏风险:嵌套Completion容易因捕获self导致循环引用,Async/Await不需要闭包,减少了这类内存管理问题。
  • 代码可维护性提升:
    • 线性流程更易读:从创建请求到解析结果,代码从上到下执行,逻辑一目了然,不用在闭包间跳转。
    • 错误处理更清晰:所有可能的错误(无效URL、网络错误、解析失败、响应异常)都通过throws抛出,调用方用do-catch统一处理即可。
    • 兼容性更好:Async/Await是Swift现代异步标准,和TaskGroup、AsyncSequence等特性兼容,后续扩展并行请求、流式处理等逻辑更方便。

内容的提问来源于stack exchange,提问作者Marcus FK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 21:15:42