许多任务中的一种方法 async/await

One method in many Tasks async/await

你好我有一个案例,我需要在多个任务中调用相同的方法。我希望有可能在并行模式下一个一个地调用这个方法(同步)。看起来像这样:

var isReadyToRefresh: Bool = true

func refresh(value: Int) async {
    try! await Task.sleep(nanoseconds: 100_000_000) // imitation API CALL
    isReadyToRefresh = false
    print("Try to refresh: \(value)")
}

func mockCallAPI(value: Int) async {
    if isReadyToRefresh {
        await refresh(value: value)
    }
}

Task {
     await mockCallAPI(value: 1)
}

Task {
     await mockCallAPI(value: 2)
}

输出:

Try to refresh: 1

Try to refresh: 2

我需要的输出:

Try to refresh: 1 OR Try to refresh 2. Depends which task has been called as first one.

有什么想法吗?

你说:

I want [the second attempt] to wait for the first refresh API finish

您可以保存对 Task 的引用,如果找到,await。如果没有找到,则开始任务:

actor Refresh {
    var task: Task<Void, Never>?

    func refresh(value: Int) async {
        try! await Task.sleep(nanoseconds: 100_000_000) // imitation API CALL
        print("Try to refresh: \(value)")
    }

    func mockCallAPI(value: Int) async {
        if let task = self.task {
            _ = await task.result
            return
        }

        task = Task {
            await refresh(value: value)
            task = nil
        }
    }
}

Apple 在随 WWDC 2021 视频一起提供的代码中展示了此模式的示例,Protect mutable state with Swift actors (but this code is not on the web site; only provided in the Developer app). See

他们的例子比较复杂(一种避免重复网络请求由某些图像发起的模式cache/downloader),但思想的核心是相同的:保存并await Task.

如果你不希望它们并行 运行 为什么它们需要在单独的任务中,等待意味着代码在任务完成后不会有任何进展,因为协作线程启动它的线程可能被用来做其他事情,比如处理更多使用交互或其他任务,事实上,因为你将它们放在单独的任务中,你要求它们并行 运行,它可能是块