使用完成处理程序和DispatchSemaphore在Swift上进行异步请求

使用完成处理程序和DispatchSemaphore在Swift上进行异步请求,swift,signals,dispatchsemaphore,Swift,Signals,Dispatchsemaphore,我正在尝试使用Alamofire的完成处理程序和调度信号量在Swift上发出async请求。我需要得到一个响应,然后将其返回给另一个方法,所以基本上这是我的代码 func customRequest(zipCode: String) -> Bool{ var response = false let dispatchQueueProcess = DispatchQueue.global(qos: .userInitiated) let semaphore = Di

我正在尝试使用
Alamofire的
完成处理程序
调度信号量
在Swift上发出
async
请求。我需要得到一个响应,然后将其返回给另一个方法,所以基本上这是我的代码

func customRequest(zipCode: String) -> Bool{
    var response = false

    let dispatchQueueProcess = DispatchQueue.global(qos: .userInitiated)
    let semaphore = DispatchSemaphore(value: 1)
    
    dispatchQueueProcess.async {
        
        semaphore.wait()

        apiRequest(zipCode: zipCode) { apiResponse in
        
            if apiResponse != nil {
            
response = apiResponse
               
             
            } else {
                print("Server did not Response")
            }
            
            semaphore.signal()
            
            
        }
    }
    
    return response
}
问题是请求总是返回
false
,因为它不等待apirest
响应。。。你有办法解决这个问题吗?非常感谢你


Ps.
apirest
返回“true”/“false”

您的返回语句在完成处理程序之外,因此它将立即运行,返回其初始false值,而不是根据需要返回请求的结果


您应该删除response属性,并在完成处理程序内处理响应。

您的返回语句在完成处理程序外,因此它将立即运行,返回其初始false值,而不是根据需要返回请求的结果


您应该删除response属性,并在完成处理程序中处理响应。

您的意图是创建一个同步函数,该函数将阻塞并等待异步请求完成吗

如果是这样的话,您就快到了,但是您需要将信号量更改为从0开始,而不是从1开始(从1减到0不会停止执行,它需要变为负数),并且需要将wait()调用移到闭包之外,否则,您不会阻止函数返回,反而会阻止闭包的完成

func自定义请求(zipCode:String)->Bool{
var响应=错误
让dispatchQueueProcess=DispatchQueue.global(qos:.userInitiated)
让信号量=分派信号量(值:0)
//在后台线程、当前函数的线程上启动异步工作
//然后,执行点将立即移动到该行
//在右括号之后
dispatchQueueProcess.async{
apiRequest(zipCode:zipCode){apiResponse in
如果让apiResponse=apiResponse{
响应=apiResponse
}否则{
打印(“服务器未响应”)
}
//告诉原始函数的线程可以继续
信号量
}
}
//启动异步工作后立即等待信号量,以便
//customRequest(zipCode:)函数在这里暂停,直到信号量被激活
//关闭时发出信号。
信号量。等待()
//一旦在异步闭包执行中发生了semaphore.signal()调用
//恢复,并且响应变量现在可以随更新的
//价值观。
返回响应
}
您可能会发现,您实际上并不希望创建这样的同步函数,因为如果从主队列调用此函数,您将冻结UI,直到收到响应为止

编辑:此示例应复制粘贴在操场上的跑步记录

<代码>导入基础 //用于模拟API调用的模板函数 func APIRESQUEST(zipCode:String,response:(Bool?)->Void){ 睡眠(3) 回答(正确) } func customRequest(zipCode:String)->Bool{ var响应=错误 让dispatchQueueProcess=DispatchQueue.global(qos:.userInitiated) 让信号量=分派信号量(值:0) dispatchQueueProcess.async{ apiRequest(zipCode:zipCode){apiResponse in 如果让apiResponse=apiResponse{ 响应=apiResponse }否则{ 打印(“服务器未响应”) } 信号量 } } 信号量。等待() 返回响应 } 打印(“结果:\(自定义请求(zipCode:“90030”)))
您是否打算创建一个同步函数,该函数将阻塞并等待异步请求完成

如果是这样的话,您就快到了,但是您需要将信号量更改为从0开始,而不是从1开始(从1减到0不会停止执行,它需要变为负数),并且需要将wait()调用移到闭包之外,否则,您不会阻止函数返回,反而会阻止闭包的完成

func自定义请求(zipCode:String)->Bool{
var响应=错误
让dispatchQueueProcess=DispatchQueue.global(qos:.userInitiated)
让信号量=分派信号量(值:0)
//在后台线程、当前函数的线程上启动异步工作
//然后,执行点将立即移动到该行
//在右括号之后
dispatchQueueProcess.async{
apiRequest(zipCode:zipCode){apiResponse in
如果让apiResponse=apiResponse{
响应=apiResponse
}否则{
打印(“服务器未响应”)
}
//告诉原始函数的线程可以继续
信号量
}
}
//启动异步工作后立即等待信号量,以便
//customRequest(zipCode:)函数在这里暂停,直到信号量被激活
//关闭时发出信号。
信号量。等待()
//一旦在异步闭包执行中发生了semaphore.signal()调用
//恢复,并且响应变量现在可以随更新的
//价值观。
返回响应
}
您可能会发现,您实际上并不希望创建这样的同步函数,因为如果从主队列调用此函数,您将冻结UI,直到收到响应为止

编辑:此示例应复制粘贴在操场上的跑步记录

<代码>导入基础 //用于模拟API调用的模板函数 func APIRESQUEST(zipCode:String,response:(Bool?)->Void){ 睡眠(3) 回答(正确) } func customRequest(zipCode:Stri)