当回调返回Twisted中的Deferred时

时间:2013-06-02 13:16:32

标签: twisted deferred

这是“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()

2 个答案:

答案 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

关键点是,当返回值是延迟时,在获得此延迟对象的结果之前,主流将不会继续。