这是“Twisted Network Programming Essential”中的一个例子:
from twisted.internet import reactor
from twisted.internet.defer import Deferred
from twisted.internet.protocol import Protocol
from twisted.web.client import Agent
import sys
from random import random
class ResourcePrinter(Protocol):
def __init__(self, finished):
self.finished = finished
def dataReceived(self, data):
print data
def connectionLost(self, reason):
self.finished.callback(None)
def printResource(response):
# Nothing added to this 'finished'
finished = Deferred()
response.deliverBody(ResourcePrinter(finished))
return finished
def printError(failure):
print >>sys.stderr, failure
def stop(result):
reactor.stop()
if len(sys.argv) != 2:
print >>sys.stderr, 'Usage'
exit(1)
agent = Agent(reactor)
d = agent.request('GET', sys.argv[1])
d.addCallbacks(printResource, printError)
d.addBoth(stop)
reactor.run()
但是因为它永远不会在addCallback()
中的finished
上调用printResource()
,为什么最终会在stop()
中调用connectionLost()
?
答案 0 :(得分:2)
这是使用名为“链接”的功能,记录在http://twistedmatrix.com/documents/current/core/howto/defer.html#auto13。
答案 1 :(得分:-1)
实际上,它不需要再添加回调。它已添加已听到:
self.finished.callback(None)
所以,让我们更加小心。代码指针听到:
d.addCallbacks(printResource, printError)
当您查看printResource代码块时,它会返回延迟作为返回值。因此,在此延迟对象获得其结果之前,数据传递将继续直到获取连接丢失事件(由协议覆盖方法捕获)并且最后一步或回调导致完成(延迟)对象,给出其结果。
Main deferred -> add callback -> callback by coming responses-> |
|
-> new deferred -> Receiving data ... til con lost -> add callaback (get result directly)|
|-> add last callback > stop
关键点是,当返回值是延迟时,在获得此延迟对象的结果之前,主流将不会继续。