您是否打算在这里创建一个同步函数,该函数将阻塞并等待异步请求完成?
如果是这样,您就快到了,但是您需要将 Semaphore 更改为从 0 而不是 1 开始(从 1 递减到 0 不会停止执行,它需要变为负数),并且您需要移动 wait()在闭包之外调用,否则您不会阻止函数返回,而是会阻止您的闭包完成。
func customRequest(zipCode: String) -> Bool {
var response = false
let dispatchQueueProcess = DispatchQueue.global(qos: .userInitiated)
let semaphore = DispatchSemaphore(value: 0)
// Start async work on background thread, current function's thread
// execution point will then immediately move to the line
// after the closing brace
dispatchQueueProcess.async {
apiRequest(zipCode: zipCode) { apiResponse in
if let apiResponse = apiResponse {
response = apiResponse
} else {
print("Server did not Response")
}
// Tell the original function's thread that it is OK to continue
semaphore.signal()
}
}
// Immediately wait for the semaphore after starting the async work so that
// the customRequest(zipCode:) function pauses here until the semaphore is
// signalled in the closure.
semaphore.wait()
// Once the semaphore.signal() call happens in the async closure execution
// resumes, and the response variable can now be returned with the updated
// value.
return response
}
您可能会发现您实际上并不想创建这样的同步函数,因为如果您从主队列中调用它,您将冻结 UI,直到收到响应。
编辑:这个例子应该复制粘贴在操场上运行
import Foundation
// template function to simulate the API call
func apiRequest(zipCode: String, response: (Bool?)->Void) {
sleep(3)
response(true)
}
func customRequest(zipCode: String) -> Bool{
var response = false
let dispatchQueueProcess = DispatchQueue.global(qos: .userInitiated)
let semaphore = DispatchSemaphore(value: 0)
dispatchQueueProcess.async {
apiRequest(zipCode: zipCode) { apiResponse in
if let apiResponse = apiResponse {
response = apiResponse
} else {
print("Server did not Response")
}
semaphore.signal()
}
}
semaphore.wait()
return response
}
print("Result: \(customRequest(zipCode: "90030"))")