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

如何在Swift 4中模拟JavaScript的async/await?DispatchQueue用法解惑

在Swift 4中模拟JavaScript的async/await逻辑(基于DispatchQueue)

嘿,我懂你想在Swift 4里复刻JavaScript那种清爽的async/await写法的需求!毕竟Swift 5.5才加入原生的async/await语法,在Swift 4里确实得靠DispatchQueue(也就是GCD,Grand Central Dispatch)来模拟类似的异步流程控制。我给你拆解下具体怎么操作,还有背后的基本逻辑~

先搞懂DispatchQueue的核心逻辑

简单来说,DispatchQueue就是苹果用来管理任务执行的“调度器”:你可以把任务(比如网络请求、耗时计算)丢到不同的队列里,GCD会自动帮你把这些任务分配到合适的线程上运行——不管是同步(等当前任务做完再执行下一个)还是异步(不用等,直接丢去后台跑)。我们要模拟async/await,核心就是用GCD的工具来控制异步任务的执行顺序,以及等待任务完成的时机。

模拟async/await的两种常用方式

首先先定义一个模拟异步请求的基础函数(比如网络调用或者耗时操作):

// 模拟异步请求:比如网络接口调用、本地文件读取
func fetchMockData(completion: @escaping (String?, Error?) -> Void) {
    // 把任务丢到全局后台队列异步执行,不阻塞当前线程
    DispatchQueue.global().async {
        // 模拟耗时操作(比如网络请求等待2秒)
        Thread.sleep(forTimeInterval: 2)
        
        // 模拟请求结果,你可以替换成真实业务逻辑
        let requestSuccess = true
        if requestSuccess {
            completion("从服务器拿到的模拟数据", nil)
        } else {
            completion(nil, NSError(domain: "com.example.app", code: 1001, userInfo: [NSLocalizedDescriptionKey: "请求失败"]))
        }
    }
}

1. 用DispatchGroup等待多个异步任务完成(类似JS的Promise.all)

如果你需要同时启动多个异步任务,等所有任务都完成后再统一处理结果,就可以用DispatchGroup来实现类似await Promise.all()的效果:

func simulateAsyncAllTasks() {
    let taskGroup = DispatchGroup()
    
    print("开始执行所有异步任务...")

    // 第一个异步任务
    taskGroup.enter() // 标记任务开始
    fetchMockData { data, error in
        defer { taskGroup.leave() } // 任务结束时标记离开
        if let data = data {
            print("任务1完成:\(data)")
        } else if let error = error {
            print("任务1出错:\(error.localizedDescription)")
        }
    }

    // 第二个异步任务
    taskGroup.enter()
    fetchMockData { data, error in
        defer { taskGroup.leave() }
        if let data = data {
            print("任务2完成:\(data)")
        } else if let error = error {
            print("任务2出错:\(error.localizedDescription)")
        }
    }

    // 所有任务完成后执行的回调,完全不会阻塞线程(推荐用这个,别用wait())
    taskGroup.notify(queue: DispatchQueue.main) {
        print("✅ 所有异步任务都完成了!可以在这里处理最终结果、更新UI")
    }
}

逻辑说明:

  • enter()相当于给任务“打卡”,告诉Group有一个任务要开始了
  • leave()是任务“下班打卡”,告诉Group这个任务结束了
  • notify()会在所有任务都完成(所有enter()都对应了leave())时,在指定队列(比如主线程)执行回调,完全不会阻塞当前线程。

2. 用DispatchSemaphore实现顺序异步任务(类似JS的await串行执行)

如果需要按顺序执行异步任务(比如先请求A,拿到A的结果再请求B),可以用DispatchSemaphore来模拟await的“等待任务完成再继续”效果:

func simulateAsyncAwaitSerial() {
    // 把所有阻塞操作放到后台队列,绝对不能在主线程执行!
    DispatchQueue.global().async {
        print("开始执行第一个任务")
        let semaphore1 = DispatchSemaphore(value: 0)
        var firstTaskResult: String?
        var firstTaskError: Error?

        // 执行第一个异步任务
        fetchMockData { data, error in
            firstTaskResult = data
            firstTaskError = error
            semaphore1.signal() // 任务完成,给信号量“发信号”
        }

        semaphore1.wait() // 等待信号量,直到任务完成(类似await)

        // 处理第一个任务结果
        guard let firstData = firstTaskResult else {
            print("第一个任务失败:\(firstTaskError?.localizedDescription ?? "未知错误")")
            return
        }
        print("第一个任务完成:\(firstData)")

        // ------------------------------
        // 用第一个任务的结果执行第二个任务
        print("开始执行第二个任务")
        let semaphore2 = DispatchSemaphore(value: 0)
        var secondTaskResult: String?
        var secondTaskError: Error?

        fetchMockData { data, error in
            secondTaskResult = data
            secondTaskError = error
            semaphore2.signal()
        }

        semaphore2.wait()

        // 处理第二个任务结果
        if let secondData = secondTaskResult {
            print("第二个任务完成:\(secondData)")
            // 回到主线程更新UI
            DispatchQueue.main.async {
                print("✅ 所有顺序任务完成,现在可以更新UI啦")
            }
        }
    }
}

逻辑说明:

  • 信号量初始值设为0,wait()会阻塞当前线程,直到signal()被调用(信号量+1)
  • 这样就实现了“等前一个异步任务完成,再执行下一段代码”的效果,和JS里的await逻辑一致。

重要注意事项

  • 绝对不要在主线程调用wait()或者信号量的wait()!会直接卡死UI,所有阻塞式等待都要放在DispatchQueue.global()这类后台队列里。
  • 如果觉得重复写信号量/Group的逻辑太繁琐,可以自己封装一个工具函数,把这些重复代码抽出来,让业务代码更接近async/await的简洁感。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:16:51