Swift async/await 相当于 Promise Kit "when" 模式

Swift async/await equivalent of Promise Kit "when" pattern

我是 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: [=14=].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() 相似,因为一旦实现了 promise,代码中的事情就会被触发。

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

问题:什么 Swift async/await 模式可以完成上述操作,类似于 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

编辑:

这就是我 return 一系列帖子及其评论的方式。 如您所见,不如 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: {[=11=].id == postid}) {
                thePosts[ndx].comments = comnts
            }
        }
        // when all done, return all post with their comments all cooked up
        return thePosts
    }
}