首页 > 解决方案 > 是否可以不将函数声明为异步并仍然在其中运行异步操作,该操作将使用完成处理程序返回值?

问题描述

我目前正在重写大量代码以使用新的异步/等待机制,但我想逐个进行,而不是更改项目中的每个文件以使用异步/等待。

我将如何转换使用完成处理程序的方法,如下所示:

func fetchLibrary(completion: ((Error?) -> Void)?) {
    apiManager.loadLibraryContent { [weak self] result in
        switch result {
        case .success(let records):
            let databaseError = self?.databaseManager.updateDatabase(withNewRecords: records)
            completion?(databaseError)
        case .failure(let error):
            completion?(error)
        }
    }
}

然后将loadLibraryContent方法更新apiManager为如下所示:

func loadLibraryContent() async throws -> [GRDBRecord] {

并且仍然可以在第一种方法中使用完成处理程序?这将使逐步迁移到 async/await 变得更容易。

理想情况下,新代码如下所示:

func fetchLibrary(completion: ((Error?) -> Void)?) {
    do {
        let records = try await apiManager.loadLibraryContent()
        let databaseError = self?.databaseManager.updateDatabase(withNewRecords: records)
        completion?(databaseError)
    } catch {
        completion?(error)
    }
}

可以用 Swift 做吗?

标签: iosswiftasync-awaitconcurrency

解决方案


您可以使用Task

    func fetchLibrary(completion: ((Error?) -> Void)?) {
        Task {
            do {
                let records = try await apiManager.loadLibraryContent()
                let databaseError = self?.databaseManager.updateDatabase(withNewRecords: records)
                completion?(databaseError)
            } catch {
                completion?(error)
            }
        }
    }

推荐阅读