如何在多回调触发后使用twisted.internet.defer.DeferredList?
twisted.internet.defer.DeferredList Let's break down what this tool does and how to use it effectively in Twisted applications:
Core Functionality
- Combine multiple Deferreds into a single callback chain: Instead of handling each Deferred's success or failure individually, wrap a group of them in a
DeferredList. This combined Deferred will only trigger its callbacks after all wrapped Deferreds have completed (whether successfully or with an error). - Structured result output: When the
DeferredListfinishes, it returns a list of tuples. Each tuple follows the format(success, result):success: A boolean (Trueif the corresponding Deferred succeeded,Falseif it failed)result: The value passed tocallback()if successful, or theFailureobject fromerrback()if failed
Key Note: Reusing Deferreds After Adding to DeferredList
A crucial point to remember—you can still interact with the original Deferred objects after adding them to a DeferredList. This is particularly useful for suppressing those pesky "Unhandled error in Deferred" warnings. For example:
If a Deferred might fail, even though the DeferredList will catch its error, Twisted may still throw an unhandled error warning unless you add an errback to the original Deferred later. Here's a quick example of how to handle this:
from twisted.internet.defer import Deferred, DeferredList from twisted.internet import reactor # Create a Deferred and add it to a DeferredList d = Deferred() dl = DeferredList([d]) # Later, add an errback to the original Deferred to suppress warnings d.addErrback(lambda failure: print(f"Quietly handled error: {failure.getErrorMessage()}")) # Trigger a failure for the Deferred d.errback(Exception("Something went wrong with this task")) # Define a callback for the DeferredList to process all results def handle_all_results(results): for success, res in results: if not success: print(f"DeferredList caught failure: {res.getErrorMessage()}") dl.addCallback(handle_all_results) reactor.run()
In this case, the DeferredList still tracks the Deferred's failure state, but we've added an errback to the original d to prevent the unhandled error warning from appearing.
内容的提问来源于stack exchange,提问作者Hatshepsut

