Google Sheet API请求打印顺序异常,Swift中如何用await解决?
问题原因
这是因为executeQuery是异步执行的网络请求方法:
- 调用
executeQuery后,主线程不会等待网络请求完成,会直接执行后续的latestLogs遍历逻辑,此时convertedLogList还未被回调代码填充数据,因此打印出空数组。 - 待网络请求完成后,才会触发闭包回调,填充
convertedLogList并打印其内容,最终导致打印顺序颠倒。
使用Swift Async/Await的解决方案
我们可以通过withCheckedThrowingContinuation将Google Sheet API的回调式异步请求转换为支持async/await的形式,让代码按预期顺序执行:
func fetchData() async { let range = "TestSheet" var convertedLogList: [Log] = [] // 将回调式请求包装为async/await形式 let values: [[Any]]? = try? await withCheckedThrowingContinuation { continuation in let query = GTLRSheetsQuery_SpreadsheetsValuesGet.query(withSpreadsheetId: Globals.shared.YOUR_SHEET_ID, range: range) Globals.shared.sheetService.executeQuery(query) { ticket, result, error in if let error = error { continuation.resume(throwing: error) return } let valueRange = result as? GTLRSheets_ValueRange continuation.resume(returning: valueRange?.values) } } guard let values = values else { print("No data found.") return } // 转换数据为Log对象数组 let fetchResult = values.map { $0.map { $0 as? String ?? "" } } for row in fetchResult { var log = Log() log.timestamp = row[0] log.nthTime = row[1] log.openNew = row[2] if row.count == 4 { log.note = row[3] } convertedLogList.append(log) } print("===== convertedLogList: ", convertedLogList) // 简化最新5条日志的获取逻辑 let latestLogs = Array(convertedLogList.reversed().prefix(5)) print("+++++ latestLogs: ", latestLogs) }
改造说明
- 将
fetchData标记为async函数,允许内部使用await等待异步操作完成。 - 通过
withCheckedThrowingContinuation封装原有的回调逻辑,把异步请求转为可等待的任务,确保网络请求完成后才继续执行后续代码。 - 优化了最新日志的获取逻辑,用
reversed().prefix(5)直接截取后转换为数组,替代原有的循环计数逻辑,更简洁高效。 - 现在代码会先完成数据获取与转换、打印
convertedLogList,再处理并打印latestLogs,输出顺序完全符合预期。
内容的提问来源于stack exchange,提问作者FYY
相关产品推荐
相关产品推荐

