【问题标题】:When a callback returns a Deferred in Twisted当回调在 Twisted 中返回 Deferred
【发布时间】:2013-06-02 13:16:32
【问题描述】:

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

但既然它从不在printResource() 中的finished 上调用addCallback(),那为什么最终会在connectionLost() 中调用stop()

【问题讨论】:

    标签: twisted deferred


    【解决方案1】:

    这是使用称为“链接”的功能,记录在 http://twistedmatrix.com/documents/current/core/howto/defer.html#auto13

    【讨论】:

      【解决方案2】:

      其实不需要再添加回调了。已添加已听:

      self.finished.callback(None)
      

      所以,让我们看的更仔细。代码指针到达听到:

      d.addCallbacks(printResource, printError)
      

      当您查看 printResource 代码块时,它会返回一个 deferred 作为返回值。因此,直到这个延迟对象获得它的结果,数据传递将继续直到获得连接丢失事件(被协议覆盖方法捕获)并且最后一步或回调导致完成(延迟)对象,给出它的结果。

      Main deferred -> add callback -> callback by coming responses-> |
                                                                      |
                                                                       -> new deferred -> Receiving data ... til con lost -> add callaback (get result directly)|
                                                                                                                                                                |-> add last callback > stop
      

      关键是,当返回值为deferred时,直到得到这个deferred对象的结果,主流程才会继续。

      【讨论】:

        猜你喜欢
        • 2018-12-03
        • 2011-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多