Swift 3 中的顺序网络请求
Sequential Network Requests in Swift 3
我有多个网络请求需要按顺序发生。他们必须等到前一个完成并收到服务器的响应。
现在我有一个死亡回调金字塔。有没有更自动化的方法来做到这一点?我尝试了一个 OperationQueue
,但它不会等待请求完成后再进入下一个请求,即使它设置为一次执行一个请求。
就其价值而言,.save
是对 CloudKit 的网络请求。没有像其他 CloudKit 操作那样的 CloudKit 订阅队列。
self.privateDB.save(subscriptions[0]){ savedSubscription, error in
//Request 1 is done
self.privateDB.save(subscriptions[1]){ savedSubscription, error in
//Request 2 is done
self.privateDB.save(subscriptions[2]){ savedSubscription, error in
//All 3 requests are done
}
}
}
我尝试了 DispatchGroup
但这似乎不起作用。所有请求似乎都在等待响应之前触发。
let group = DispatchGroup()
//Create a subscription for every record type
for subscription in subscriptions{
group.enter()
//...
self.privateDB.save(subscription){ savedSubscription, error in
group.leave()
}
}
group.wait()
有什么想法吗?
尝试使用信号量使它们同步。
创建信号量
var 信号量 = dispatch_semaphore_create(0)
等待第一个 api 调用完成
dispatch_semaphore_wait(信号量,DISPATCH_TIME_FOREVER)
在第一次 api 完成时发出信号量。
dispatch_semaphore_signal(信号量)
例如:
var 信号量 = dispatch_semaphore_create(0)
self.privateDB.save(subscriptions[0]){ savedSubscription, 错误
dispatch_semaphore_signal(信号量)
}
dispatch_semaphore_wait(信号量,DISPATCH_TIME_FOREVER)
self.privateDB.save(订阅[1]){ savedSubscription, error in}
您应该能够创建一个或多个 CKModifySubscriptionsOperation
来保存订阅,然后使用 CKDatabase.add()
到 运行 它们。如果您需要它们 运行 的顺序,请设置它们之间的依赖关系以确保它们 运行 的顺序:
let subscriptionOp1 = CKModifySubscriptionsOperation(subscriptionsToSave: subscriptions[0], subscriptionsToDelete: nil)
let subscriptionOp2 = CKModifySubscriptionsOperation(subscriptionsToSave: subscriptions[1], subscriptionsToDelete: nil)
let subscriptionOp3 = CKModifySubscriptionsOperation(subscriptionsToSave: subscriptions[2], subscriptionsToDelete: nil)
subscriptionOp2.addDependency(subscriptionOp1)
subscriptionOp3.addDependency(subscriptionOp2)
database.add(subscriptionOp1)
database.add(subscriptionOp2)
database.add(subscriptionOp3)
我有多个网络请求需要按顺序发生。他们必须等到前一个完成并收到服务器的响应。
现在我有一个死亡回调金字塔。有没有更自动化的方法来做到这一点?我尝试了一个 OperationQueue
,但它不会等待请求完成后再进入下一个请求,即使它设置为一次执行一个请求。
就其价值而言,.save
是对 CloudKit 的网络请求。没有像其他 CloudKit 操作那样的 CloudKit 订阅队列。
self.privateDB.save(subscriptions[0]){ savedSubscription, error in
//Request 1 is done
self.privateDB.save(subscriptions[1]){ savedSubscription, error in
//Request 2 is done
self.privateDB.save(subscriptions[2]){ savedSubscription, error in
//All 3 requests are done
}
}
}
我尝试了 DispatchGroup
但这似乎不起作用。所有请求似乎都在等待响应之前触发。
let group = DispatchGroup()
//Create a subscription for every record type
for subscription in subscriptions{
group.enter()
//...
self.privateDB.save(subscription){ savedSubscription, error in
group.leave()
}
}
group.wait()
有什么想法吗?
尝试使用信号量使它们同步。
创建信号量
var 信号量 = dispatch_semaphore_create(0)
等待第一个 api 调用完成
dispatch_semaphore_wait(信号量,DISPATCH_TIME_FOREVER)
在第一次 api 完成时发出信号量。
dispatch_semaphore_signal(信号量)
例如:
var 信号量 = dispatch_semaphore_create(0) self.privateDB.save(subscriptions[0]){ savedSubscription, 错误 dispatch_semaphore_signal(信号量) } dispatch_semaphore_wait(信号量,DISPATCH_TIME_FOREVER) self.privateDB.save(订阅[1]){ savedSubscription, error in}
您应该能够创建一个或多个 CKModifySubscriptionsOperation
来保存订阅,然后使用 CKDatabase.add()
到 运行 它们。如果您需要它们 运行 的顺序,请设置它们之间的依赖关系以确保它们 运行 的顺序:
let subscriptionOp1 = CKModifySubscriptionsOperation(subscriptionsToSave: subscriptions[0], subscriptionsToDelete: nil)
let subscriptionOp2 = CKModifySubscriptionsOperation(subscriptionsToSave: subscriptions[1], subscriptionsToDelete: nil)
let subscriptionOp3 = CKModifySubscriptionsOperation(subscriptionsToSave: subscriptions[2], subscriptionsToDelete: nil)
subscriptionOp2.addDependency(subscriptionOp1)
subscriptionOp3.addDependency(subscriptionOp2)
database.add(subscriptionOp1)
database.add(subscriptionOp2)
database.add(subscriptionOp3)