Bonjour et merci d'avance pour votre temps.Quelle est la bonne façon de travailler avec les objets AWSTask dans Swift?
Dans mon code, je fais diverses demandes à AWSSQS qui retournent toutes AWSTask. J'ai trouvé que travailler avec ces objets AWSTask était très difficile tout en essayant de garder toute la logique spécifique à AWS dans une seule classe afin de pouvoir facilement passer à un service de cloud différent si besoin est.
Idéalement, ce que je voudrais faire est d'exécuter une série de tâches AWS de manière asynchrone de manière sérielle. Normalement, je voudrais simplement ajouter des tâches à une file d'attente de répartition de série personnalisée, mais comme les objets AWSTask sont eux-mêmes des tâches asynchrones, je ne peux pas le faire.
Voici un exemple simple qui illustre le problème que j'ai. Il n'a pas de but réel, mais il illustre bien le problème. Ci-dessous, j'ai un code pour créer une file d'attente SQS, envoyer un message à une file d'attente SQS, recevoir un message d'une file d'attente SQS et supprimer une file d'attente SQS. Disons que je veux faire ces quatre choses de manière sérielle et asynchrone. En d'autres termes, je veux m'assurer que la tâche précédente a réussi avant d'essayer la tâche suivante.
ViewController
DispatchQueue.global(qos: DispatchQoS.QoSClass.userInitiated).async {
awsClass.runTest()
DispatchQueue.main.async {
print("Test Finished")
}
}
AwsClass
public func createQueue(){
guard let createQueueRequest = AWSSQSCreateQueueRequest() else{fatalError()}
createQueueRequest.queueName = "TestQueue"
sqs.createQueue(createQueueRequest).continueWith(block: {(task) -> AnyObject? in
if task.error != nil {
print(task.error!)
}
else if task.result != nil {
self.queueUrl = task.result!.queueUrl!
print("created queue at: \(self.queueUrl!)")
}
return nil
})
}
public func deleteQueue(){
if queueUrl != nil {
guard let deleteQueueRequest = AWSSQSDeleteQueueRequest() else{fatalError()}
deleteQueueRequest.queueUrl = queueUrl
sqs.deleteQueue(deleteQueueRequest).continueWith(block: {(task) -> AnyObject? in
if task.error != nil {
print(task.error!)
}
else if task.result != nil {
print("queue sucessfully deleted from \(self.queueUrl!)")
self.queueUrl = nil
}
return nil
})
}
else{
print("Queue has already been deleted")
}
}
public func sendMessage(messageData: String, toConnectId: String) {
guard let sendMessageRequest = AWSSQSSendMessageRequest() else{fatalError()}
sendMessageRequest.queueUrl = toConnectId
sendMessageRequest.delaySeconds = 0
sendMessageRequest.messageBody = messageData
sqs.sendMessage(sendMessageRequest).continueWith(block: {(task) -> AnyObject? in
if task.error != nil {
print(task.error!)
}
else if task.result != nil {
print("successfully sent message to \(toConnectId)")
}
return nil
})
}
public func receiveMessage(){
guard let receiveMessageRequest = AWSSQSReceiveMessageRequest() else{fatalError()}
receiveMessageRequest.queueUrl = self.queueUrl
receiveMessageRequest.maxNumberOfMessages = 1
sqs.receiveMessage(receiveMessageRequest).continueWith(block: {(task) -> AnyObject? in
if task.error != nil {
print(task.error!)
}
else if task.result != nil {
let message = (task.result?.messages?.first)!
print("successfully received message with body: \(message.body ?? "failed")")
}
return nil
})
}
public func runTest(){
let mySerialQueue = DispatchQueue(label: "mySerialQueue")
mySerialQueue.sync {
self.createQueue()
}
mySerialQueue.sync {
self.sendMessage(messageData: "test", toConnectId: "https://someUrl")
}
mySerialQueue.sync {
self.receiveMessage()
}
mySerialQueue.sync {
self.deleteQueue()
}
}
Depuis les AWSTasks sont asynchrones avec des fonctions d'achèvement, le code fait rapidement tous les quatre appels, puis les fonctions d'achèvement sont appelés à chaque fois que terminent ces tâches. Au lieu de cela, je veux que la fonction d'achèvement de la première tâche se termine avant que la tâche suivante ne commence.