<?xml version="1.0"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><title>Twisted Documentation: Deferred Reference</title><link href="../howto/stylesheet.css" type="text/css" rel="stylesheet" /></head><body bgcolor="white"><h1 class="title">Deferred Reference</h1><div class="toc"><ol><li><a href="#auto0">Callbacks</a></li><ul><li><a href="#auto1">Multiple callbacks</a></li><li><a href="#auto2">Visual Explanation</a></li></ul><li><a href="#auto3">Errbacks</a></li><ul><li><a href="#auto4">Unhandled Errors</a></li></ul><li><a href="#auto5">Handling either synchronous or asynchronous results</a></li><ul><li><a href="#auto6">Handling possible Deferreds in the library code</a></li></ul><li><a href="#auto7">DeferredList</a></li><ul><li><a href="#auto8">Other behaviours</a></li></ul><li><a href="#auto9">Class Overview</a></li><ul><li><a href="#auto10">Basic Callback Functions</a></li><li><a href="#auto11">Chaining Deferreds</a></li></ul><li><a href="#auto12">See also</a></li></ol></div><div class="content"><span></span><p>This document is a guide to the behaviour of the <code class="API">twisted.internet.defer.Deferred</code> object, and to various ways you can use them when they are returned by functions.</p><p>This document assumes that you are familiar with the basic principle that the Twisted framework is structured around: asynchronous, callback-based programming, where instead of having blocking code in your program or using threads to run blocking code, you have functions that return immediately and then begin a callback chain when data is available.</p><p>See these documents for more information:</p><ul><li><a href="async.html">Asynchronous Programming with Twisted</a></li></ul><p> After reading this document, the reader should expect to be able to deal with most simple APIs in Twisted and Twisted-using code that return Deferreds. </p><ul><li>what sorts of things you can do when you get a Deferred from a function call; and</li><li>how you can write your code to robustly handle errors in Deferred code.</li></ul><p>Unless you're already very familiar with asynchronous programming, it's strongly recommended you read the <a href="async.html#deferreds">Deferreds section</a> of the Asynchronous programming document to get an idea of why Deferreds exist. </p><h2>Callbacks<a name="auto0"></a></h2><p>A <code class="API">twisted.internet.defer.Deferred</code> 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 deferred mechanism standardizes the application programmer's interface with all sorts of blocking or delayed operations.</p><pre class="python"> <span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>, <span class="py-src-variable">defer</span> <span class="py-src-keyword">def</span> <span class="py-src-identifier">getDummyData</span>(<span class="py-src-parameter">x</span>): <span class="py-src-string">""" This function is a dummy which simulates a delayed result and returns a Deferred which will fire with that result. Don't try too hard to understand this. """</span> <span class="py-src-variable">d</span> = <span class="py-src-variable">defer</span>.<span class="py-src-variable">Deferred</span>() <span class="py-src-comment"># simulate a delayed result by asking the reactor to fire the </span> <span class="py-src-comment"># Deferred in 2 seconds time with the result x * 3 </span> <span class="py-src-variable">reactor</span>.<span class="py-src-variable">callLater</span>(<span class="py-src-number">2</span>, <span class="py-src-variable">d</span>.<span class="py-src-variable">callback</span>, <span class="py-src-variable">x</span> * <span class="py-src-number">3</span>) <span class="py-src-keyword">return</span> <span class="py-src-variable">d</span> <span class="py-src-keyword">def</span> <span class="py-src-identifier">printData</span>(<span class="py-src-parameter">d</span>): <span class="py-src-string">""" Data handling function to be added as a callback: handles the data by printing the result """</span> <span class="py-src-keyword">print</span> <span class="py-src-variable">d</span> <span class="py-src-variable">d</span> = <span class="py-src-variable">getDummyData</span>(<span class="py-src-number">3</span>) <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">printData</span>) <span class="py-src-comment"># manually set up the end of the process by asking the reactor to </span><span class="py-src-comment"># stop itself in 4 seconds time </span><span class="py-src-variable">reactor</span>.<span class="py-src-variable">callLater</span>(<span class="py-src-number">4</span>, <span class="py-src-variable">reactor</span>.<span class="py-src-variable">stop</span>) <span class="py-src-comment"># start up the Twisted reactor (event loop handler) manually </span><span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>() </pre><h3>Multiple callbacks<a name="auto1"></a></h3><p>Multiple callbacks can be added to a Deferred. The first callback in the Deferred's callback chain will be called with the result, the second with the result of the first callback, and so on. Why do we need this? Well, consider a Deferred returned by twisted.enterprise.adbapi - the result of a SQL query. A web widget might add a callback that converts this result into HTML, and pass the Deferred onwards, where the callback will be used by twisted to return the result to the HTTP client. The callback chain will be bypassed in case of errors or exceptions.</p><pre class="python"> <span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span>, <span class="py-src-variable">defer</span> <span class="py-src-keyword">class</span> <span class="py-src-identifier">Getter</span>: <span class="py-src-keyword">def</span> <span class="py-src-identifier">gotResults</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">x</span>): <span class="py-src-string">""" The Deferred mechanism provides a mechanism to signal error conditions. In this case, odd numbers are bad. This function demonstrates a more complex way of starting the callback chain by checking for expected results and choosing whether to fire the callback or errback chain """</span> <span class="py-src-keyword">if</span> <span class="py-src-variable">x</span> % <span class="py-src-number">2</span> == <span class="py-src-number">0</span>: <span class="py-src-variable">self</span>.<span class="py-src-variable">d</span>.<span class="py-src-variable">callback</span>(<span class="py-src-variable">x</span>*<span class="py-src-number">3</span>) <span class="py-src-keyword">else</span>: <span class="py-src-variable">self</span>.<span class="py-src-variable">d</span>.<span class="py-src-variable">errback</span>(<span class="py-src-variable">ValueError</span>(<span class="py-src-string">"You used an odd number!"</span>)) <span class="py-src-keyword">def</span> <span class="py-src-identifier">_toHTML</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">r</span>): <span class="py-src-string">""" This function converts r to HTML. It is added to the callback chain by getDummyData in order to demonstrate how a callback passes its own result to the next callback """</span> <span class="py-src-keyword">return</span> <span class="py-src-string">"Result: %s"</span> % <span class="py-src-variable">r</span> <span class="py-src-keyword">def</span> <span class="py-src-identifier">getDummyData</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">x</span>): <span class="py-src-string">""" The Deferred mechanism allows for chained callbacks. In this example, the output of gotResults is first passed through _toHTML on its way to printData. Again this function is a dummy, simulating a delayed result using callLater, rather than using a real asynchronous setup. """</span> <span class="py-src-variable">self</span>.<span class="py-src-variable">d</span> = <span class="py-src-variable">defer</span>.<span class="py-src-variable">Deferred</span>() <span class="py-src-comment"># simulate a delayed result by asking the reactor to schedule </span> <span class="py-src-comment"># gotResults in 2 seconds time </span> <span class="py-src-variable">reactor</span>.<span class="py-src-variable">callLater</span>(<span class="py-src-number">2</span>, <span class="py-src-variable">self</span>.<span class="py-src-variable">gotResults</span>, <span class="py-src-variable">x</span>) <span class="py-src-variable">self</span>.<span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">_toHTML</span>) <span class="py-src-keyword">return</span> <span class="py-src-variable">self</span>.<span class="py-src-variable">d</span> <span class="py-src-keyword">def</span> <span class="py-src-identifier">printData</span>(<span class="py-src-parameter">d</span>): <span class="py-src-keyword">print</span> <span class="py-src-variable">d</span> <span class="py-src-keyword">def</span> <span class="py-src-identifier">printError</span>(<span class="py-src-parameter">failure</span>): <span class="py-src-keyword">import</span> <span class="py-src-variable">sys</span> <span class="py-src-variable">sys</span>.<span class="py-src-variable">stderr</span>.<span class="py-src-variable">write</span>(<span class="py-src-variable">str</span>(<span class="py-src-variable">failure</span>)) <span class="py-src-comment"># this series of callbacks and errbacks will print an error message </span><span class="py-src-variable">g</span> = <span class="py-src-variable">Getter</span>() <span class="py-src-variable">d</span> = <span class="py-src-variable">g</span>.<span class="py-src-variable">getDummyData</span>(<span class="py-src-number">3</span>) <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">printData</span>) <span class="py-src-variable">d</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">printError</span>) <span class="py-src-comment"># this series of callbacks and errbacks will print "Result: 12" </span><span class="py-src-variable">g</span> = <span class="py-src-variable">Getter</span>() <span class="py-src-variable">d</span> = <span class="py-src-variable">g</span>.<span class="py-src-variable">getDummyData</span>(<span class="py-src-number">4</span>) <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">printData</span>) <span class="py-src-variable">d</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">printError</span>) <span class="py-src-variable">reactor</span>.<span class="py-src-variable">callLater</span>(<span class="py-src-number">4</span>, <span class="py-src-variable">reactor</span>.<span class="py-src-variable">stop</span>); <span class="py-src-variable">reactor</span>.<span class="py-src-variable">run</span>() </pre><h3>Visual Explanation<a name="auto2"></a></h3><div hlint="off" align="center"><img src="../img/deferred-attach.png" /></div><ol><li>Requesting method (data sink) requests data, gets Deferred object.</li><li>Requesting method attaches callbacks to Deferred object.</li></ol><img src="../img/deferred-process.png" hlint="off" align="left" /><ol><li>When the result is ready, give it to the Deferred object. <code>.callback(result)</code> if the operation succeeded, <code>.errback(failure)</code> if it failed. Note that <code>failure</code> is typically an instance of a <code class="API">twisted.python.failure.Failure</code> instance.</li><li>Deferred object triggers previously-added (call/err)back with the <code>result</code> or <code>failure</code>. Execution then follows the following rules, going down the chain of callbacks to be processed. <ul><li>Result of the callback is always passed as the first argument to the next callback, creating a chain of processors.</li><li>If a callback raises an exception, switch to errback.</li><li>An unhandled failure gets passed down the line of errbacks, this creating an asynchronous analog to a series to a series of <code>except:</code> statements.</li><li>If an errback doesn't raise an exception or return a <code class="API">twisted.python.failure.Failure</code> instance, switch to callback.</li></ul></li></ol><br hlint="off" clear="all" /><h2>Errbacks<a name="auto3"></a></h2><p>Deferred's error handling is modeled after Python's exception handling. In the case that no errors occur, all the callbacks run, one after the other, as described above.</p><p>If the errback is called instead of the callback (e.g. because a DB query raised an error), then a <code class="API">twisted.python.failure.Failure</code> is passed into the first errback (you can add multiple errbacks, just like with callbacks). You can think of your errbacks as being like <code class="python">except</code> blocks of ordinary Python code.</p><p>Unless you explicitly <code class="python">raise</code> an error in except block, the <code class="python">Exception</code> is caught and stops propagating, and normal execution continues. The same thing happens with errbacks: unless you explicitly <code class="python">return</code> a <code class="python">Failure</code> or (re-)raise an exception, the error stops propagating, and normal callbacks continue executing from that point (using the value returned from the errback). If the errback does returns a <code class="python">Failure</code> or raise an exception, then that is passed to the next errback, and so on.</p><p><em>Note:</em> If an errback doesn't return anything, then it effectively returns <code class="python">None</code>, meaning that callbacks will continue to be executed after this errback. This may not be what you expect to happen, so be careful. Make sure your errbacks return a <code class="python">Failure</code> (probably the one that was passed to it), or a meaningful return value for the next callback.</p><p>Also, <code class="API">twisted.python.failure.Failure</code> instances have a useful method called trap, allowing you to effectively do the equivalent of:</p><pre class="python"> <span class="py-src-keyword">try</span>: <span class="py-src-comment"># code that may throw an exception </span> <span class="py-src-variable">cookSpamAndEggs</span>() <span class="py-src-keyword">except</span> (<span class="py-src-variable">SpamException</span>, <span class="py-src-variable">EggException</span>): <span class="py-src-comment"># Handle SpamExceptions and EggExceptions </span> ... </pre><p>You do this by:</p><pre class="python"> <span class="py-src-keyword">def</span> <span class="py-src-identifier">errorHandler</span>(<span class="py-src-parameter">failure</span>): <span class="py-src-variable">failure</span>.<span class="py-src-variable">trap</span>(<span class="py-src-variable">SpamException</span>, <span class="py-src-variable">EggException</span>) <span class="py-src-comment"># Handle SpamExceptions and EggExceptions </span> <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">cookSpamAndEggs</span>) <span class="py-src-variable">d</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">errorHandler</span>) </pre><p>If none of arguments passed to <code class="python">failure.trap</code> match the error encapsulated in that <code class="python">Failure</code>, then it re-raises the error.</p><p>There's another potential <q>gotcha</q> here. There's a method <code class="API">twisted.internet.defer.Deferred.addCallbacks</code> which is similar to, but not exactly the same as, <code class="python">addCallback</code> followed by <code class="python">addErrback</code>. In particular, consider these two cases:</p><pre class="python"> <span class="py-src-comment"># Case 1 </span><span class="py-src-variable">d</span> = <span class="py-src-variable">getDeferredFromSomewhere</span>() <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">callback1</span>) <span class="py-src-comment"># A</span> <span class="py-src-variable">d</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">errback1</span>) <span class="py-src-comment"># B</span> <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">callback2</span>) <span class="py-src-variable">d</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">errback2</span>) <span class="py-src-comment"># Case 2 </span><span class="py-src-variable">d</span> = <span class="py-src-variable">getDeferredFromSomewhere</span>() <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallbacks</span>(<span class="py-src-variable">callback1</span>, <span class="py-src-variable">errback1</span>) <span class="py-src-comment"># C</span> <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallbacks</span>(<span class="py-src-variable">callback2</span>, <span class="py-src-variable">errback2</span>) </pre><p>If an error occurs in <code class="python">callback1</code>, then for Case 1 <code class="python">errback1</code> will be called with the failure. For Case 2, <code class="python">errback2</code> will be called. Be careful with your callbacks and errbacks.</p><p>What this means in a practical sense is in Case 1, "A" will handle a success condition from <code>getDeferredFromSomewhere</code>, and "B" will handle any errors that occur <em>from either the upstream source, or that occur in 'A'</em>. In Case 2, "C"'s errback1 <em>will only handle an error condition raised by <code>getDeferredFromSomewhere</code></em>, it will not do any handling of errors raised in callback1.</p><h3>Unhandled Errors<a name="auto4"></a></h3><p>If a Deferred is garbage-collected with an unhandled error (i.e. it would call the next errback if there was one), then Twisted will write the error's traceback to the log file. This means that you can typically get away with not adding errbacks and still get errors logged. Be careful though; if you keep a reference to the Deferred around, preventing it from being garbage-collected, then you may never see the error (and your callbacks will mysteriously seem to have never been called). If unsure, you should explicitly add an errback after your callbacks, even if all you do is:</p><pre class="python"> <span class="py-src-comment"># Make sure errors get logged </span><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">python</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">log</span> <span class="py-src-variable">d</span>.<span class="py-src-variable">addErrback</span>(<span class="py-src-variable">log</span>.<span class="py-src-variable">err</span>) </pre><h2>Handling either synchronous or asynchronous results<a name="auto5"></a></h2><p> In some applications, there are functions that might be either asynchronous or synchronous. For example, a user authentication function might be able to check in memory whether a user is authenticated, allowing the authentication function to return an immediate result, or it may need to wait on network data, in which case it should return a Deferred to be fired when that data arrives. However, a function that wants to check if a user is authenticated will then need to accept both immediate results <em> and</em> Deferreds. </p><p> In this example, the library function <code>authenticateUser</code> uses the application function <code>isValidUser</code> to authenticate a user: </p><pre class="python"> <span class="py-src-keyword">def</span> <span class="py-src-identifier">authenticateUser</span>(<span class="py-src-parameter">isValidUser</span>, <span class="py-src-parameter">user</span>): <span class="py-src-keyword">if</span> <span class="py-src-variable">isValidUser</span>(<span class="py-src-variable">user</span>): <span class="py-src-keyword">print</span> <span class="py-src-string">"User is authenticated"</span> <span class="py-src-keyword">else</span>: <span class="py-src-keyword">print</span> <span class="py-src-string">"User is not authenticated"</span> </pre><p> However, it assumes that <code>isValidUser</code> returns immediately, whereas <code>isValidUser</code> may actually authenticate the user asynchronously and return a Deferred. It is possible to adapt this trivial user authentication code to accept either a synchronous <code>isValidUser</code> or an asynchronous <code>isValidUser</code>, allowing the library to handle either type of function. It is, however, also possible to adapt synchronous functions to return Deferreds. This section describes both alternatives: handling functions that might be synchronous or asynchronous in the library function (<code>authenticateUser</code>) or in the application code. </p><h3>Handling possible Deferreds in the library code<a name="auto6"></a></h3><p> Here is an example of a synchronous user authentication function that might be passed to <code>authenticateUser</code>: </p><div class="py-listing"><pre> <span class="py-src-keyword">def</span> <span class="py-src-identifier">synchronousIsValidUser</span>(<span class="py-src-parameter">user</span>): <span class="py-src-string">''' Return true if user is a valid user, false otherwise '''</span> <span class="py-src-keyword">return</span> <span class="py-src-variable">user</span> <span class="py-src-keyword">in</span> [<span class="py-src-string">"Alice"</span>, <span class="py-src-string">"Angus"</span>, <span class="py-src-string">"Agnes"</span>] </pre><div class="caption">Source listing - <a href="listings/deferred/synch-validation.py"><span class="filename">listings/deferred/synch-validation.py</span></a></div></div><p> However, here's an <code>asynchronousIsValidUser</code> function that returns a Deferred: </p><pre class="python"> <span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">reactor</span> <span class="py-src-keyword">def</span> <span class="py-src-identifier">asynchronousIsValidUser</span>(<span class="py-src-parameter">d</span>, <span class="py-src-parameter">user</span>): <span class="py-src-variable">d</span> = <span class="py-src-variable">Deferred</span>() <span class="py-src-variable">reactor</span>.<span class="py-src-variable">callLater</span>(<span class="py-src-number">2</span>, <span class="py-src-variable">d</span>.<span class="py-src-variable">callback</span>, <span class="py-src-variable">user</span> <span class="py-src-keyword">in</span> [<span class="py-src-string">"Alice"</span>, <span class="py-src-string">"Angus"</span>, <span class="py-src-string">"Agnes"</span>]) <span class="py-src-keyword">return</span> <span class="py-src-variable">d</span> </pre><p> Our original implementation of <code>authenticateUser</code> expected <code>isValidUser</code> to be synchronous, but now we need to change it to handle both synchronous and asynchronous implementations of <code>isValidUser</code>. For this, we use <code base="twisted.internet.defer" class="API">maybeDeferred</code> to call <code>isValidUser</code>, ensuring that the result of <code>isValidUser</code> is a Deferred, even if <code>isValidUser</code> is a synchronous function: </p><pre class="python"> <span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">defer</span> <span class="py-src-keyword">def</span> <span class="py-src-identifier">printResult</span>(<span class="py-src-parameter">result</span>): <span class="py-src-keyword">if</span> <span class="py-src-variable">result</span>: <span class="py-src-keyword">print</span> <span class="py-src-string">"User is authenticated"</span> <span class="py-src-keyword">else</span>: <span class="py-src-keyword">print</span> <span class="py-src-string">"User is not authenticated"</span> <span class="py-src-keyword">def</span> <span class="py-src-identifier">authenticateUser</span>(<span class="py-src-parameter">isValidUser</span>, <span class="py-src-parameter">user</span>): <span class="py-src-variable">d</span> = <span class="py-src-variable">defer</span>.<span class="py-src-variable">maybeDeferred</span>(<span class="py-src-variable">isValidUser</span>, <span class="py-src-variable">user</span>) <span class="py-src-variable">d</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">printResult</span>) </pre><p> Now <code>isValidUser</code> could be either <code>synchronousIsValidUser</code> or <code>asynchronousIsValidUser</code>. </p><p>It is also possible to modify <code>synchronousIsValidUser</code> to return a Deferred, see <a href="gendefer.html">Generating Deferreds</a> for more information.</p><h2>DeferredList<a name="auto7"></a></h2><p>Sometimes you want to be notified after several different events have all happened, rather than waiting for each one individually. For example, you may want to wait for all the connections in a list to close. <code class="API">twisted.internet.defer.DeferredList</code> is the way to do this.</p><p>To create a DeferredList from multiple Deferreds, you simply pass a list of the Deferreds you want it to wait for:</p><pre class="python"> <span class="py-src-comment"># Creates a DeferredList </span><span class="py-src-variable">dl</span> = <span class="py-src-variable">defer</span>.<span class="py-src-variable">DeferredList</span>([<span class="py-src-variable">deferred1</span>, <span class="py-src-variable">deferred2</span>, <span class="py-src-variable">deferred3</span>]) </pre><p>You can now treat the DeferredList like an ordinary Deferred; you can call <code>addCallbacks</code> and so on. The DeferredList will call its callback when all the deferreds have completed. The callback will be called with a list of the results of the Deferreds it contains, like so:</p><pre class="python"> <span class="py-src-keyword">def</span> <span class="py-src-identifier">printResult</span>(<span class="py-src-parameter">result</span>): <span class="py-src-keyword">print</span> <span class="py-src-variable">result</span> <span class="py-src-variable">deferred1</span> = <span class="py-src-variable">defer</span>.<span class="py-src-variable">Deferred</span>() <span class="py-src-variable">deferred2</span> = <span class="py-src-variable">defer</span>.<span class="py-src-variable">Deferred</span>() <span class="py-src-variable">deferred3</span> = <span class="py-src-variable">defer</span>.<span class="py-src-variable">Deferred</span>() <span class="py-src-variable">dl</span> = <span class="py-src-variable">defer</span>.<span class="py-src-variable">DeferredList</span>([<span class="py-src-variable">deferred1</span>, <span class="py-src-variable">deferred2</span>, <span class="py-src-variable">deferred3</span>]) <span class="py-src-variable">dl</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">printResult</span>) <span class="py-src-variable">deferred1</span>.<span class="py-src-variable">callback</span>(<span class="py-src-string">'one'</span>) <span class="py-src-variable">deferred2</span>.<span class="py-src-variable">errback</span>(<span class="py-src-string">'bang!'</span>) <span class="py-src-variable">deferred3</span>.<span class="py-src-variable">callback</span>(<span class="py-src-string">'three'</span>) <span class="py-src-comment"># At this point, dl will fire its callback, printing: </span><span class="py-src-comment"># [(1, 'one'), (0, 'bang!'), (1, 'three')] </span><span class="py-src-comment"># (note that defer.SUCCESS == 1, and defer.FAILURE == 0) </span></pre><p>A standard DeferredList will never call errback.</p><div class="note"><strong>Note: </strong><p>If you want to apply callbacks to the individual Deferreds that go into the DeferredList, you should be careful about when those callbacks are added. The act of adding a Deferred to a DeferredList inserts a callback into that Deferred (when that callback is run, it checks to see if the DeferredList has been completed yet). The important thing to remember is that it is <em>this callback</em> which records the value that goes into the result list handed to the DeferredList's callback.</p><!-- TODO: add picture here: three columns of callback chains, with a value being snarfed out of the middle of each and handed off to the DeferredList --><p>Therefore, if you add a callback to the Deferred <em>after</em> adding the Deferred to the DeferredList, the value returned by that callback will not be given to the DeferredList's callback. To avoid confusion, we recommend not adding callbacks to a Deferred once it has been used in a DeferredList.</p></div><pre class="python"> <span class="py-src-keyword">def</span> <span class="py-src-identifier">printResult</span>(<span class="py-src-parameter">result</span>): <span class="py-src-keyword">print</span> <span class="py-src-variable">result</span> <span class="py-src-keyword">def</span> <span class="py-src-identifier">addTen</span>(<span class="py-src-parameter">result</span>): <span class="py-src-keyword">return</span> <span class="py-src-variable">result</span> + <span class="py-src-string">" ten"</span> <span class="py-src-comment"># Deferred gets callback before DeferredList is created </span><span class="py-src-variable">deferred1</span> = <span class="py-src-variable">defer</span>.<span class="py-src-variable">Deferred</span>() <span class="py-src-variable">deferred2</span> = <span class="py-src-variable">defer</span>.<span class="py-src-variable">Deferred</span>() <span class="py-src-variable">deferred1</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">addTen</span>) <span class="py-src-variable">dl</span> = <span class="py-src-variable">defer</span>.<span class="py-src-variable">DeferredList</span>([<span class="py-src-variable">deferred1</span>, <span class="py-src-variable">deferred2</span>]) <span class="py-src-variable">dl</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">printResult</span>) <span class="py-src-variable">deferred1</span>.<span class="py-src-variable">callback</span>(<span class="py-src-string">"one"</span>) <span class="py-src-comment"># fires addTen, checks DeferredList, stores "one ten"</span> <span class="py-src-variable">deferred2</span>.<span class="py-src-variable">callback</span>(<span class="py-src-string">"two"</span>) <span class="py-src-comment"># At this point, dl will fire its callback, printing: </span><span class="py-src-comment"># [(1, 'one ten'), (1, 'two')] </span> <span class="py-src-comment"># Deferred gets callback after DeferredList is created </span><span class="py-src-variable">deferred1</span> = <span class="py-src-variable">defer</span>.<span class="py-src-variable">Deferred</span>() <span class="py-src-variable">deferred2</span> = <span class="py-src-variable">defer</span>.<span class="py-src-variable">Deferred</span>() <span class="py-src-variable">dl</span> = <span class="py-src-variable">defer</span>.<span class="py-src-variable">DeferredList</span>([<span class="py-src-variable">deferred1</span>, <span class="py-src-variable">deferred2</span>]) <span class="py-src-variable">deferred1</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">addTen</span>) <span class="py-src-comment"># will run *after* DeferredList gets its value</span> <span class="py-src-variable">dl</span>.<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">printResult</span>) <span class="py-src-variable">deferred1</span>.<span class="py-src-variable">callback</span>(<span class="py-src-string">"one"</span>) <span class="py-src-comment"># checks DeferredList, stores "one", fires addTen</span> <span class="py-src-variable">deferred2</span>.<span class="py-src-variable">callback</span>(<span class="py-src-string">"two"</span>) <span class="py-src-comment"># At this point, dl will fire its callback, printing: </span><span class="py-src-comment"># [(1, 'one), (1, 'two')] </span></pre><h3>Other behaviours<a name="auto8"></a></h3><p>DeferredList accepts three keyword arguments that modify its behaviour: <code>fireOnOneCallback</code>, <code>fireOnOneErrback</code> and <code>consumeErrors</code>. If <code>fireOnOneCallback</code> is set, the DeferredList will immediately call its callback as soon as any of its Deferreds call their callback. Similarly, <code>fireOnOneErrback</code> will call errback as soon as any of the Deferreds call their errback. Note that DeferredList is still one-shot, like ordinary Deferreds, so after a callback or errback has been called the DeferredList will do nothing further (it will just silently ignore any other results from its Deferreds).</p><p>The <code>fireOnOneErrback</code> option is particularly useful when you want to wait for all the results if everything succeeds, but also want to know immediately if something fails.</p><p>The <code>consumeErrors</code> argument will stop the DeferredList from propagating any errors along the callback chains of any Deferreds it contains (usually creating a DeferredList has no effect on the results passed along the callbacks and errbacks of their Deferreds). Stopping errors at the DeferredList with this option will prevent <q>Unhandled error in Deferred</q> warnings from the Deferreds it contains without needing to add extra errbacks<a href="#footnote-1" title="Unless of course a later callback starts a fresh error &mdash; but as we've already noted, adding callbacks to a Deferred after its used in a DeferredList is confusing and usually avoided."><super>1</super></a>.</p><a name="class"></a><h2>Class Overview<a name="auto9"></a></h2><p>This is an overview API reference for Deferred from the point of using a Deferred returned by a function. It is not meant to be a substitute for the docstrings in the Deferred class, but can provide guidelines for its use.</p><p>There is a parallel overview of functions used by the Deferred's <em>creator</em> in <a href="gendefer.html#class">Generating Deferreds</a>.</p><h3>Basic Callback Functions<a name="auto10"></a></h3><ul><li><code class="py-prototype">addCallbacks(self, callback[, errback, callbackArgs, errbackArgs, errbackKeywords, asDefaults])</code><p>This is the method you will use to interact with Deferred. It adds a pair of callbacks <q>parallel</q> to each other (see diagram above) in the list of callbacks made when the Deferred is called back to. The signature of a method added using addCallbacks should be <code>myMethod(result, *methodArgs, **methodKeywords)</code>. If your method is passed in the callback slot, for example, all arguments in the tuple <code>callbackArgs</code> will be passed as <code>*methodArgs</code> to your method.</p><p>There are various convenience methods that are derivative of addCallbacks. I will not cover them in detail here, but it is important to know about them in order to create concise code.</p><ul><li><code class="py-prototype">addCallback(callback, *callbackArgs, **callbackKeywords)</code><p>Adds your callback at the next point in the processing chain, while adding an errback that will re-raise its first argument, not affecting further processing in the error case.</p><p>Note that, while addCallbacks (plural) requires the arguments to be passed in a tuple, addCallback (singular) takes all its remaining arguments as things to be passed to the callback function. The reason is obvious: addCallbacks (plural) cannot tell whether the arguments are meant for the callback or the errback, so they must be specifically marked by putting them into a tuple. addCallback (singular) knows that everything is destined to go to the callback, so it can use Python's <q>*</q> and <q>**</q> syntax to collect the remaining arguments.</p></li><li><code class="py-prototype">addErrback(errback, *errbackArgs, **errbackKeywords)</code><p>Adds your errback at the next point in the processing chain, while adding a callback that will return its first argument, not affecting further processing in the success case.</p></li><li><code class="py-prototype">addBoth(callbackOrErrback, *callbackOrErrbackArgs, **callbackOrErrbackKeywords)</code><p>This method adds the same callback into both sides of the processing chain at both points. Keep in mind that the type of the first argument is indeterminate if you use this method! Use it for <code>finally:</code> style blocks.</p></li></ul></li></ul><h3>Chaining Deferreds<a name="auto11"></a></h3><p>If you need one Deferred to wait on another, all you need to do is return a Deferred from a method added to addCallbacks. Specifically, if you return Deferred B from a method added to Deferred A using A.addCallbacks, Deferred A's processing chain will stop until Deferred B's .callback() method is called; at that point, the next callback in A will be passed the result of the last callback in Deferred B's processing chain at the time.</p><p>If this seems confusing, don't worry about it right now -- when you run into a situation where you need this behavior, you will probably recognize it immediately and realize why this happens. If you want to chain deferreds manually, there is also a convenience method to help you.</p><ul><li><code class="py-prototype">chainDeferred(otherDeferred)</code><p>Add <code>otherDeferred</code> to the end of this Deferred's processing chain. When self.callback is called, the result of my processing chain up to this point will be passed to <code>otherDeferred.callback</code>. Further additions to my callback chain do not affect <code>otherDeferred</code></p><p>This is the same as <code class="python">self.addCallbacks(otherDeferred.callback, otherDeferred.errback)</code></p></li></ul><h2>See also<a name="auto12"></a></h2><ol><li><a href="gendefer.html">Generating Deferreds</a>, an introduction to writing asynchronous functions that return Deferreds.</li></ol><h2>Footnotes</h2><ol><li><a name="footnote-1"><span xmlns="http://www.w3.org/1999/xhtml" class="footnote">Unless of course a later callback starts a fresh error — but as we've already noted, adding callbacks to a Deferred after its used in a DeferredList is confusing and usually avoided.</span></a></li></ol></div><p><a href="../howto/index.html">Index</a></p><span class="version">Version: 2.5.0</span></body></html>