Swift async/await 等效于 Promise Kit“when”模式

问题描述

我是 Swift 新手,来自 JS,我已经开始构建 iOS 应用。

最初我选择了使用 Promise Kit 来处理异步内容,因为对我来说它比我读到的其他东西更容易。

无论如何,在 JS 中,我经常使用以下模式:

async function doAyncFunction(item) {
  try {
    // do async call to fetch data using item
    return Promise.resolve(data);
  } catch (error) {
    return Promise.reject(error);
  }
}
const promises = items.map((item) => doAyncFunction(item));
const results = await Promise.all(promises);

我最终使用 Promise Kit 完成了这样的工作:

func doManyAsyncRequests(userIds: [String],accesstoken: String) -> Promise<Void> {
  Promise { seal in
    let promises = spotifyUserIds.map {
      doSingleAsyncRequest(userId: $0.id,accesstoken: accesstoken) // this function returns a promise
    }
    when(fulfilled: promises).done { results in
      print("Results: \(results)")
      // process results
    }.catch { error in
      print("\(error)")
      // handle error
    }
  }
}

Promise Kit 的 when 与 JavaScript 的 Promise.all() 类似,因为一旦承诺被实现,事情就会被触发在代码中移动。

由于我的学习曲线很慢,我决定开始为 iOS 15 编码并使用 Swift async/await。

问题:什么 Swift 异步/等待模式可以完成上述操作,类似于 Promise Kit 的 wait 和 JavaScript 的 Promise.all()

谢谢。

更新:感谢@workingdog,他帮助我找到了下面的解决方案。我现在必须处理错误,但现在这一个不同的主题

func getAllThings(users: [User],accesstoken: String) async -> [Thing] {
    var allThings: [Thing] = []
    await withTaskGroup(of: [Thing].self) { group in
        for user in users {
            group.async {
                let userThings = await self.getUsersThings(
                    accesstoken: accesstoken,displayName: user.displayName,userId: user.id
                )
                return userThings
            }
        }
        for await (userThings) in group {
            allThings = allThings + userThings
        }
    }
    return allThings
}

解决方法

您可能正在寻找withTaskGroup(...),例如:

func getAll() async {
    await withTaskGroup(of: Void.self) { group in
        await getPosts()
        for post in posts {
            group.async { await self.getCommentsFor(post: post) }
        }
    }
}

我已经在 github 上设置了自己的基本测试来学习这个:https://github.com/workingDog/TestAsync

编辑:

这是我将如何返回带有评论的帖子数组。 正如你所看到的,不如 getAll()。

func getAllPosts() async -> [Post] {
    // this is the tricky parameter bit,the tuple returned when you call group.async {...}
    await withTaskGroup(of: (Int,[Comment]).self) { group in
        // get all the posts
        var thePosts: [Post] = await fetchThem()
        // for each post get all the comments (concurrently)
        for post in thePosts {
            group.async {
                let comments: [Comment] = await self.fetchThem(with: post)
                return (post.id,comments)
            }
        }
        // add the comments to their corresponding post (concurrently)
        for await (postid,comnts) in group {
            if let ndx = thePosts.firstIndex(where: {$0.id == postid}) {
                thePosts[ndx].comments = comnts
            }
        }
        // when all done,return all post with their comments all cooked up
        return thePosts
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...