Structure d'objet différé
Deferred se compose d'une série de chaînes de rappel appariées, chaque paire contient un rappel pour la gestion du succès (rappels) et un rappel pour la gestion des erreurs (errbacks). Initialement, les différés seront constitués de deux chaînes de rappel vides. Lorsque vous leur ajoutez des rappels, ils seront toujours ajoutés par paires. Lorsque le résultat du traitement asynchrone revient, les Deferred démarreront et déclencheront la chaîne de rappel dans l'ordre dans lequel ils ont été ajoutés.
Il peut être plus facile d'illustrer avec des exemples. Tout d'abord, jetons un coup d'œil à addCallback :
from twisted.internet.defer import Deferred def myCallback(result): print result d = Deferred() d.addCallback(myCallback) d.callback("Triggering callback.")
L'exécuter obtiendra les résultats suivants :
Triggering callback.
Dans l'exemple ci-dessus, un différé est créé et sa méthode addCallback est utilisée pour enregistrer un rappel pour la gestion réussie. d.callback démarrera en différé et appellera la chaîne de rappel. Les paramètres passés dans le rappel seront également reçus par la première fonction de chaque chaîne de rappel.
Avec addCallback, je pense que je peux aussi deviner que l'autre mauvaise branche est addErrorback. Regardons un exemple :
from twisted.internet.defer import Deferred def myErrback(failure): print failure d = Deferred() d.addErrback(myErrback) d.errback(ValueError("Triggering errback."))
L'exécuter vous donnera les résultats suivants : Résultat :
[Failure instance: Traceback (failure with no frames): <type 'exceptions.ValueError'>: Triggering errback.]
On peut voir que Twisted encapsulera les erreurs dans Failure.
Il est à noter que comme mentionné précédemment, les rappels enregistrés se font toujours par paires. Lorsque nous utilisons les méthodes d.addCallback et d.addErrorback, il semble que nous ajoutions simplement un rappel ou un errback. En fait, afin de compléter la création de ce niveau de chaîne de rappel, ces méthodes enregistreront également un pass-through pour l'autre moitié. N'oubliez pas que les chaînes de rappel ont toujours la même longueur. Si vous souhaitez spécifier respectivement le rappel et l'errback de ce niveau de rappel. Vous pouvez utiliser la méthode d.addCallbacks :
d = Deferred() d.addCallbacks(myCallback, myErrback) d.callback("Triggering callback.")
Alors... arrêtons-nous ici aujourd'hui.
Exemple avancé
Ensuite, nous devrions faire quelque chose de plus pratique, c'est-à-dire le mettre dans Reactor. Regardons d'abord un exemple :
from twisted.internet import reactor, defer class HeadlineRetriever(object): def processHeadline(self, headline): if len(headline) > 50: self.d.errback(Exception("The headline ``%s'' is too long!" % (headline,))) else: self.d.callback(headline) def _toHTML(self, result): return "<h1>%s</h1>" % (result,) def getHeadline(self, input): self.d = defer.Deferred() reactor.callLater(1, self.processHeadline, input) self.d.addCallback(self._toHTML) return self.d def printData(result): print result reactor.stop() def printError(failure): print failure reactor.stop() h = HeadlineRetriever() d = h.getHeadline("Breaking News: Twisted Takes us to the Moon!") d.addCallbacks(printData, printError) reactor.run()
L'exemple ci-dessus reçoit un titre et le traite si le titre est trop long, une erreur trop longue sera renvoyée. être converti en HTML et traité.
Étant donné que le titre donné comporte moins de 50 caractères, l'exécution du code ci-dessus entraînera le retour suivant :
<h1>Breaking News: Twisted Takes us to the Moon!</h1>
Une chose à noter est qu'il s'agissait utilisé ci-dessus La méthode callLater du réacteur peut être utilisée pour créer des événements chronométrés pour simuler une requête asynchrone.
Si on rend le titre très long, par exemple :
h = HeadlineRetriever() d = h.getHeadline("1234567890"*6) d.addCallbacks(printData, printError)
Le résultat est attendu :
[Failure instance: Traceback (failure with no frames): <type 'exceptions.Exception'>: The headline ``123456789012345678901234567890123456789012345678901234567890'' is too long!]
On utilise le schéma pour regarder le processus de déclenchement :
Les points clés des Deferreds
1 seront déclenchés lorsque leur rappel ou errback est appelé
2. Si vous essayez de déclencher plusieurs fois, une exception DéjàCalledError en résultera ;
3. Les exceptions dans le rappel ou l'errback de niveau N1 seront transmises à l'errback de niveau N1, s'il n'y a pas d'errback, une erreur non gérée sera générée. Si le rappel ou l'erreur de niveau N ne renvoie pas d'exception ou ne renvoie pas d'objet Échec, il sera traité par le rappel de niveau N
4. Le résultat renvoyé dans le rappel sera transmis au niveau suivant ; premier paramètre ;
5. Si l'erreur passée dans errback n'est pas un objet Failure, elle sera automatiquement enveloppée une fois.
Pour plus d'exemples analysant l'utilisation des objets différés dans le framework Twisted de Python, veuillez prêter attention au site Web PHP chinois pour les articles connexes !