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
}
}
我是 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
}
}