I'm trying to figure out how can i make my code more asynchronous using twisted.
deferred_obj.callback
however chained callbacks will not be considered asynchronous because they're chained and the event loop will keep firing each one of them concurrently until there is no more, right?
However, if I have a deferred object, and I attach as its callback the deferred_obj.callback as in d.addCallback(deferred_obj.callback)
then this will be considered asynchronous, because the deferred_obj is waiting for the data, and then the method that will pass the data is waiting on data as well, however once i d.callback 'd' object processes the data then it call deferred_obj.callback however since this object is deferred, unlike the case of chained callbacks, it will execute asynchronously... correct?
Assuming all of my code is non-blocking, this means that chained callbacks are NOT asynchronous while chained deferreds are, correct?
twisted. internet. defer. Deferred objects are one of the key concepts that you should understand in order to develop asynchronous code that uses the Twisted framework: they are a signal to the calling function that a result is pending.
Deferred is a promise that a function will at some point have a result. We can attach callback functions to a Deferred, and once it gets a result these callbacks will be called. In addition Deferreds allow the developer to register a callback for an error, with the default behavior of logging the error.
The callbacks are (by default) synchronous. However, as the Twisted doc points out:
If you need one Deferred to wait on another, all you need to do is return a Deferred from a method added to addCallbacks.
So you can use that to do some asynchronous processing in your callback chain. Let's do that:
from twisted.internet import reactor, defer
def callback_func_2(result, previous_data):
# here we pass the result of the deferred down the callback chain
# (done synchronously)
print "calling function 1 on result:%s with previous result:%s" % (result, previous_data)
return result
def callback_func(result):
#let's do some asynchronous stuff in this callback
# simple trick here is to return a deferred from a callback
# instead of the result itself.
#
# so we can do asynchronous stuff here,
# like firing something 1 second later and have
# another method processing the result
print "calling function 1 on result:%s" % result
d = defer.Deferred()
reactor.callLater(1, d.callback, "second callback")
d.addCallback(callback_func_2, result)
return d
def do():
d = defer.Deferred()
reactor.callLater(1, d.callback, "first callback")
d.addCallback(callback_func)
return d
do()
reactor.run()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With