在 Swift 中顺序执行异步函数的多个调用

问题描述 投票:0回答:1

假设我有一个异步函数:

func doAsyncWork() async throws { ... }

该函数可以从多个地方调用。我想要实现的是确保该函数永远不会同时执行多次。例如,如果有人在第一个调用者仍在执行该函数时调用该函数,则它应该将第二个调用排队,直到第一个调用完成(依此类推,并进行适当的错误传播)。必须保留调用的顺序,因此可能需要诸如 FIFO 队列之类的东西来存储尚未处理的调用。

我想避免仅出于此目的使用 RxSwift 等外部库/框架,因此我正在寻找一个普通的 Swift 解决方案。有什么想法吗?

swift asynchronous
1个回答
0
投票

我与 ChatGPT“讨论”了我的问题,我们最终得到了这样的效果,效果很好(但也许有更好的解决方案):

import Foundation

class SerializedFunctionCaller {
    private let serialQueue = DispatchQueue(label: "com.yourapp.serializedFunctionQueue")
    
    // Define a generic async function that can throw an error
    func callAsyncFunction<T>(_ function: @escaping () async throws -> T) async throws -> T {
        return try await withCheckedThrowingContinuation { continuation in
            // Use a serial queue for serialized access
            serialQueue.async {
                Task {
                    do {
                        // Call the async function and pass the result to the continuation
                        let result = try await function()
                        continuation.resume(returning: result)
                    } catch {
                        // If an error occurs, pass the error to the continuation
                        continuation.resume(throwing: error)
                    }
                }
            }
        }
    }
}

// Example usage:
let serializedCaller = SerializedFunctionCaller()

// Define your async function
func yourAsyncFunction() async throws {
    // Your async work here
    print("Function started at \(Date())")
    try await Task.sleep(nanoseconds: 1_000_000_000 * 1) // 1 sec
    print("Function finished at \(Date())")
}

// Call the function from multiple places

Task {
    do {
        try await serializedCaller.callAsyncFunction(yourAsyncFunction)
        try await serializedCaller.callAsyncFunction(yourAsyncFunction)
    } catch {
        print(error)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.