如何让3个并行下载任务返回结果时立即更新State而非等待全部完成?
问题:异步下载任务完成后立即更新对应@State变量
我有3个下载任务,当前使用的代码会等3个任务全部完成后才统一更新@State变量,希望每个任务的结果返回后立即更新对应的变量,请问该如何实现?
原代码如下:
@State private var imageURL1: String @State private var imageURL2: String @State private var imageURL3: String Button { Task { async let first = download(url: one) async let second = download(url: two) async let third = download(url: three) imageURL1 = await first imageURL2 = await second imageURL3 = await third } }
解决方案
你当前的写法里,虽然三个async let会同时启动下载任务,但后续的await是按顺序执行的——代码会先等第一个任务完成并更新imageURL1,才会处理第二个任务的结果,以此类推,所以做不到完成一个就更新一个。
要实现目标,只需把每个下载任务放到独立的Task中即可:
// 注意:@State变量需要初始化值 @State private var imageURL1: String = "" @State private var imageURL2: String = "" @State private var imageURL3: String = "" Button { // 第一个任务:完成后立即更新imageURL1 Task { imageURL1 = await download(url: one) } // 第二个任务:完成后立即更新imageURL2 Task { imageURL2 = await download(url: two) } // 第三个任务:完成后立即更新imageURL3 Task { imageURL3 = await download(url: three) } }
原理说明
每个独立的Task会并发执行对应的下载操作,当某个任务的await download(...)完成时,会立刻将结果赋值给对应的@State变量,触发视图更新,完全不需要等待其他任务结束。
如果你的下载任务数量不固定,也可以用循环批量创建任务:
// 假设你有一个URL数组和对应的状态数组 @State private var imageURLs: [String] = Array(repeating: "", count: 3) let urls = [one, two, three] Button { for index in urls.indices { Task { imageURLs[index] = await download(url: urls[index]) } } }
内容的提问来源于stack exchange,提问作者erotsppa
相关产品推荐
相关产品推荐

