Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops 异步调用和For循环_Loops_Asynchronous_Alamofire_Get Request - Fatal编程技术网

Loops 异步调用和For循环

Loops 异步调用和For循环,loops,asynchronous,alamofire,get-request,Loops,Asynchronous,Alamofire,Get Request,我最近在Alamofire上遇到了一个问题(通常是异步调用) 我有两种型号,清单和用户。清单中包含用户的电子邮件,我还想知道用户的名字和姓氏(我知道我也可以在后端解决这个问题,但是,我想看看是否有前端解决方案,因为这个问题也会出现在更复杂的问题上) 目前,我正在发出一个GET请求来获取所有列表,我正在遍历它们,并发出另一个GET请求来获取firstname,lastname。 我需要等待获取此get请求的结果,或者至少将其附加到我的清单字典中。同样,在我做任何其他事情之前(转到我的应用程序的下一

我最近在Alamofire上遇到了一个问题(通常是异步调用)

我有两种型号,清单和用户。清单中包含用户的电子邮件,我还想知道用户的名字和姓氏(我知道我也可以在后端解决这个问题,但是,我想看看是否有前端解决方案,因为这个问题也会出现在更复杂的问题上)

目前,我正在发出一个GET请求来获取所有列表,我正在遍历它们,并发出另一个GET请求来获取firstname,lastname。 我需要等待获取此get请求的结果,或者至少将其附加到我的清单字典中。同样,在我做任何其他事情之前(转到我的应用程序的下一个屏幕),我希望所有的列表都链接到一个firstname,lastname。因为有一个循环,这似乎特别会导致一些问题(即,如果只是两个嵌套的GET请求,它可能在回调中)。有没有一个简单的方法来解决这个问题。我已在下面附上psuedocode:

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)
    }
}