Loops 异步调用和For循环
我最近在Alamofire上遇到了一个问题(通常是异步调用) 我有两种型号,清单和用户。清单中包含用户的电子邮件,我还想知道用户的名字和姓氏(我知道我也可以在后端解决这个问题,但是,我想看看是否有前端解决方案,因为这个问题也会出现在更复杂的问题上) 目前,我正在发出一个GET请求来获取所有列表,我正在遍历它们,并发出另一个GET请求来获取firstname,lastname。 我需要等待获取此get请求的结果,或者至少将其附加到我的清单字典中。同样,在我做任何其他事情之前(转到我的应用程序的下一个屏幕),我希望所有的列表都链接到一个firstname,lastname。因为有一个循环,这似乎特别会导致一些问题(即,如果只是两个嵌套的GET请求,它可能在回调中)。有没有一个简单的方法来解决这个问题。我已在下面附上psuedocode:Loops 异步调用和For循环,loops,asynchronous,alamofire,get-request,Loops,Asynchronous,Alamofire,Get Request,我最近在Alamofire上遇到了一个问题(通常是异步调用) 我有两种型号,清单和用户。清单中包含用户的电子邮件,我还想知道用户的名字和姓氏(我知道我也可以在后端解决这个问题,但是,我想看看是否有前端解决方案,因为这个问题也会出现在更复杂的问题上) 目前,我正在发出一个GET请求来获取所有列表,我正在遍历它们,并发出另一个GET请求来获取firstname,lastname。 我需要等待获取此get请求的结果,或者至少将其附加到我的清单字典中。同样,在我做任何其他事情之前(转到我的应用程序的下一
GET Request to grab listings:
for each listing:
GET request to grab first_name, last_name
Once all listings have gotten first_name, last_name -> Load next page
下面是一个可能的解决方案:
GET Request to grab listings:
var n = the number of listings
var i = 0 //the number of retrieved
for each listing:
GET request to grab first_name, last_name, callback: function(response){
assign first/last name using response.
i+=1
if(i==n)
load_next_page()
}
因此,它所做的是保留一个计数器,记录您获取的firstname/lastname记录的数量。确保您能够处理调用获取名称失败的情况
或者,正如在对这个问题的评论中所建议的,你可以使用承诺。它们使异步代码变得更好。您的问题的答案称为
调度组
当调度组中当前没有代码时,只能输入和保留调度组以执行某些代码
GET Request to grab listings{
var downloadGroup = dispatch_group_create()
//Create a dispatch group
for each listing{
dispatch_group_enter(downloadGroup)
//Enter the dispatch group
GET request to grab first_name, last_name (Async){
dispatch_group_leave(downloadGroup)
//Leave the dispatch group
}
}
dispatch_group_notify(downloadGroup, dispatch_get_main_queue()) {
//Run this code when all GET requests are finished
}
}
如本代码所示
关于派遣的资料来源和有趣的阅读材料:Ray Wenderlich提供了Scala风格的未来和承诺,您可以这样做:
let future: Future<[Listing]> = fetchListings().flatMap { listings in
listings.traverse { listing in
fetchUser(listing.userId).map { user in
listing.userName = "\(user.firstName) \(user.lastName)"
return listing
}
}
}
Scala风格的未来和承诺库:或
下面是一个现成的代码示例,您可以将其粘贴到游乐场文件中,以试验上述任何库(适用于FutureLib,BrightFutures可能需要稍加修改)
导入FutureLib
进口基金会
导入运动场
XCPlaygroundPage.currentPage.needsIndefiniteExecution=true
类列表{
让userId:Int
init(userId:Int){
self.userId=userId
userName=“”
}
var用户名:String
}
结构用户{
让id:Int
让firstName:String
让lastName:String
init(uid:Int,firstName:String,lastName:String){
self.id=id
self.firstName=firstName
self.lastName=lastName
}
}
func fetchListings()->Future{
NSLog(“开始获取列表…”)
返回承诺。解析后(1.0){
NSLog(“已完成获取列表”)
return(1…10).map{Listing(userId:$0)}
}.未来!
}
//给定用户ID,获取用户:
func fetchUser(id:Int)->Future{
NSLog(“开始获取用户[\(id)]…”)
返回承诺。解析后(1.0){
NSLog(“已完成获取用户[\(id)]”)
返回用户(id,firstName:“first\(id)”,lastName:“last\(id)”)
}.未来!
}
让future:future=fetchListings().flatMap{listings进入
listings.traverse{正在登录
fetchUser(listing.userId).map{user in
listing.userName=“\(user.firstName)\(user.lastName)”
返回列表
}
}
}
future.onSuccess{listings in
1.forEach{
打印($0.userName)
}
}
Use和Hmm它们似乎依赖于Javascript。Swift有承诺吗?当然,它们依赖于Javascript,您问了一个Javascript问题(带有Javascript标记)。我不知道什么是Swift
。如果I===n
但服务器还没有返回响应,那么伪代码中会发生什么情况?在GET请求的回调中应该发生I+=1以获取名称。
future.onSuccess { listings in
listings.forEach {
print($0.userName)
}
}
import FutureLib
import Foundation
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
class Listing {
let userId: Int
init(userId: Int) {
self.userId = userId
userName = ""
}
var userName: String
}
struct User {
let id: Int
let firstName: String
let lastName: String
init (_ id: Int, firstName: String, lastName: String) {
self.id = id
self.firstName = firstName
self.lastName = lastName
}
}
func fetchListings() -> Future<[Listing]> {
NSLog("start fetching listings...")
return Promise.resolveAfter(1.0) {
NSLog("finished fetching listings.")
return (1...10).map { Listing(userId: $0) }
}.future!
}
// Given a user ID, fetch a user:
func fetchUser(id: Int) -> Future<User> {
NSLog("start fetching user[\(id)]...")
return Promise.resolveAfter(1.0) {
NSLog("finished fetching user[\(id)].")
return User(id, firstName: "first\(id)", lastName: "last\(id)")
}.future!
}
let future: Future<[Listing]> = fetchListings().flatMap { listings in
listings.traverse { listing in
fetchUser(listing.userId).map { user in
listing.userName = "\(user.firstName) \(user.lastName)"
return listing
}
}
}
future.onSuccess { listings in
listings.forEach {
print($0.userName)
}
}