有没有一种通用的方法来处理 swift 中的异步和抛出组合

is there a generic way of handling combinations of async and throws in swift

我发现关于 swift 并发性的文档很少 - 所以我发现我必须构建我自己的大部分异步工具,即使它们可能已经存在于某处。

但是,在大多数情况下,我需要为基本相同的函数制作四份副本。例如 - 假设我想要一个实际的适当异步“运行 延迟这么长的函数” - 我最终得到

    //
    // do this after this amount of time
    //
    public static func after<T>( ms : Int, function : () -> T) async -> T
    {
        await delay(ms: ms)
        return function()
    }

    //
    // do this after this amount of time
    //
    public static func after<T>( ms : Int, function : () throws -> T) async throws -> T
    {
        await delay(ms: ms)
        return try function()
    }

    //
    // do this after this amount of time
    //
    public static func after<T>( ms : Int, function : () async -> T) async -> T
    {
        await delay(ms: ms)
        return await function()
    }
    
    //
    // do this after this amount of time
    //
    public static func after<T>( ms : Int, function : () async throws -> T) async throws -> T
    {
        await delay(ms: ms)
        return try await function()
    }

所以我想知道是否有任何方法可以在一个函数中这样说 - 基本上是说“并且它应该与具有 async/throw 任意组合的函数一起使用”

您可以简单地使用此语法来获得最通用的解决方案:

func after<T>(ms: Int, function: () async throws -> T) async rethrows -> T {
    delay(ms: ms)
    return try await function()
}

rethrows:只在内部函数抛出时抛出

async:也可以将同步函数传给异步部分;没关系

示例:

// No error thrown (no need for try); function is not async
let a = await after(ms: 10) { return 1 }

// No error thrown; function is async
let b = await after(ms: 10) { return await after(ms: 20) { return 2 } }

// Error thrown (try needed); function is not async
let c = try await after(ms: 10) { throw NSError() }

// Error thrown; function is async
let d = try await after(ms: 10) { return try await after(ms: 20) { throw NSError() } }