Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.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
Swift 如何能够执行一个接一个完成的多个Alamofire请求?_Swift_Alamofire_Nsoperationqueue - Fatal编程技术网

Swift 如何能够执行一个接一个完成的多个Alamofire请求?

Swift 如何能够执行一个接一个完成的多个Alamofire请求?,swift,alamofire,nsoperationqueue,Swift,Alamofire,Nsoperationqueue,我想执行多个Alamofire请求。但是,由于数据依赖性,新请求只能在前一个请求完成时启动 我已经用一个更一般的异步请求示例询问了一个问题,该问题通过OperationQueue解决。然而,我并没有成功地用阿拉莫菲尔实现同样的目标 public func performAlamofireRequest(_ number: Int, success: @escaping (Int) -> Void)->Void { Alamofire.request(String(format

我想执行多个Alamofire请求。但是,由于数据依赖性,新请求只能在前一个请求完成时启动

我已经用一个更一般的异步请求示例询问了一个问题,该问题通过
OperationQueue
解决。然而,我并没有成功地用阿拉莫菲尔实现同样的目标

public func performAlamofireRequest(_ number: Int, success: @escaping (Int) -> Void)->Void {
    Alamofire.request(String(format: "http://jsonplaceholder.typicode.com/posts/%i", number+1)) // NSURLSession dispatch queue
        .responseString { response in // Completion handler at main dispatch queue? 
            if response.result.isSuccess {
             //   print("data")
            } else if response.result.isFailure {
             //   print("error")
            }
            success(number) // Always leave closure in this example
    }
}
为了确保在启动下一个请求之前完成请求,我使用
OperationQueue
,如下所示:

let operationQueue = OperationQueue.main
for operationNumber in 0..<4 { // Create some operations
    let operation = BlockOperation(block: {
        performAlamofireRequest(operationNumber) { number in
            print("Operation #\(number) finished")
    }
})
operation.name = "Operation #\(operationNumber)"

    if operationNumber > 0 {
        operation.addDependency(operationQueue.operations.last!)
    }
    operationQueue.addOperation(operation)
}
这显然是不正确的


阿拉莫菲尔如何实现这一目标

问题与您提出的问题相同:操作依赖于完成一个操作,如文档所述,但是您已经编写了代码,在异步调度请求以供将来执行后,操作将退出(您创建并添加到队列中的操作将按照其依赖项设置的顺序完成,但请求将由基础Alamofire的NSURLSession并发激发)

例如,如果需要串行执行,可以执行以下操作:

// you should create an operation queue, not use OperationQueue.main here –
// synchronous network IO that would end up waiting on main queue is a real bad idea.
let operationQueue = OperationQueue()
let timeout:TimeInterval = 30.0

for operationNumber in 0..<4 {
    let operation = BlockOperation {
        let s = DispatchSemaphore(value: 0)
        self.performAlamofireRequest(operationNumber) { number in
            // do stuff with the response.
            s.signal()
        }

        // the timeout here is really an extra safety measure – the request itself should time out and end up firing the completion handler.
        s.wait(timeout: DispatchTime(DispatchTime.now, Int64(timeout * Double(NSEC_PER_SEC))))
    }

    operationQueue.addOperation(operation)
}
//您应该创建操作队列,而不是在此处使用OperationQueue.main——
//最终会在主队列上等待的同步网络IO是一个非常糟糕的主意。
让operationQueue=operationQueue()
let timeout:TimeInterval=30.0

对于0..中的operationNumber,问题与您提出的问题相同:操作依赖于完成一个操作,如文档所述,但您已经编写了代码,在异步调度请求以供将来执行后,操作将退出(您创建并添加到队列中的操作将按照其依赖项设置的顺序完成,但请求将由基础Alamofire的NSURLSession并发激发)

例如,如果需要串行执行,可以执行以下操作:

// you should create an operation queue, not use OperationQueue.main here –
// synchronous network IO that would end up waiting on main queue is a real bad idea.
let operationQueue = OperationQueue()
let timeout:TimeInterval = 30.0

for operationNumber in 0..<4 {
    let operation = BlockOperation {
        let s = DispatchSemaphore(value: 0)
        self.performAlamofireRequest(operationNumber) { number in
            // do stuff with the response.
            s.signal()
        }

        // the timeout here is really an extra safety measure – the request itself should time out and end up firing the completion handler.
        s.wait(timeout: DispatchTime(DispatchTime.now, Int64(timeout * Double(NSEC_PER_SEC))))
    }

    operationQueue.addOperation(operation)
}
//您应该创建操作队列,而不是在此处使用OperationQueue.main——
//最终会在主队列上等待的同步网络IO是一个非常糟糕的主意。
让operationQueue=operationQueue()
let timeout:TimeInterval=30.0

对于0中的operationNumber.。这很有效,并且再次给出了一个明确的解释!我也同意操作队列不应该使用主队列。但是,如果仍然使用
OperationQueue.main
,我希望会出现一个UI块,但似乎根本没有调用Alamofire的completionHandler(因此信号量没有发出信号)。虽然我不会以这种方式实现它,但我希望理解它为什么不工作…如果使用
OperationQueue.main
执行上面的阻塞操作,则不会触发回调的原因,信号量
wait
调用在阻塞操作内进行,并将阻塞主队列。如果没有超时在这种情况下,这将导致死锁。这种基于信号量的路由也可能存在另一个难看的微妙错误:如果在我上面的例子中超时时间比执行请求的NSURLSession/NSURLRequest的超时时间短,则块操作完成,然后回调将在稍后某个时间触发。我远离sema当我可以的时候,请回答:)这很有效,再次给出一个清晰的解释!我也同意操作队列不应该使用主队列。但是,如果仍然使用
OperationQueue.main
,我希望会有一个UI块,但似乎根本没有调用Alamofire的completionHandler(因此信号量没有发出信号)。虽然我不会以这种方式实现它,但我希望理解它为什么不工作…如果使用
OperationQueue.main
执行上面的阻塞操作,则不会触发回调的原因,信号量
wait
调用在阻塞操作内进行,并将阻塞主队列。如果没有超时在这种情况下,这将导致死锁。这种基于信号量的路由也可能存在另一个难看的微妙错误:如果在我上面的例子中超时时间比执行请求的NSURLSession/NSURLRequest的超时时间短,则块操作完成,然后回调将在稍后某个时间触发。我远离sem当我可以的时候,请说:)