【问题标题】:How to do a HTTP Get request with a deferred inside another (cascade defer)?如何在另一个内部延迟(级联延迟)执行 HTTP Get 请求?
【发布时间】:2016-05-30 14:00:24
【问题描述】:

我想做一个 GET 请求来检查返回码是否符合我的预期。该请求发生在由通用延迟链的 addCallback 调用的函数内部,如下面的代码所示。

我的具体问题是:如何使-D-线的返回到达-E-线?

似乎从未调用回调函数“cbResponse”(行-D-)。我的第一次尝试是执行请求并将请求的结果返回到回调链(行-A-)。它失败了,因为 deferr 对象没有属性结果。 第二次尝试(行-B-)是返回延迟对象本身。它也不返回结果。 第三次尝试(-C-行),什么都返回,但显然没有请求的响应代码。

非常感谢!

from twisted.web.client import Agent
from twisted.web.http_headers import Headers
from twisted.internet import reactor, defer

class Test (object):


    @classmethod
    def getRequest (self, result):

        print "Function getRequest"

        agent = Agent(reactor)

        d2 = agent.request('GET',
                           'http://www.google.com',
                           Headers({'User-Agent': ['Twisted Web Client Example']}),
                           None)

        d2.addCallback(Test.cbResponse)

        # 1 st attempt: return the result of d2. Fail: exceptions.AttributeError: Deferred instance has no attribute 'result'
        return d2.result            # --> line A

        # 2nd attempt: return only the deferr object d2. Don't fail, but I can't get the result of the above request
        ### return d2                   # --> line B

        # 3rd attemp: return None (without return). 
                                    # --> line C   

    @classmethod
    def cbResponse(response):

        print 'Function cbResponse %s', response.code
        # This is the return value I want to pass back to deferredChain function (called at line E)
        return response.code            # line --> D

    @classmethod
    def deferredChain(self):
        d = defer.Deferred()

        d.addCallback(Test.getRequest)  # line --> E
        d.callback("success")

        return d.result                 # line --> F



if __name__ == '__main__':
    tst = Test()
    rtn = tst.deferredChain()
    print "RTN: %s " % rtn

【问题讨论】:

  • 请改写问题,因为不清楚什么是问题,什么是问题。
  • 对不起@pinturic,我做了调整。请看看现在是否清楚。

标签: python twisted deferred


【解决方案1】:

您正在使用Twisted Agent,这需要运行反应器才能正常工作,请参阅文档中的链接示例。如果您启动 Twisted reactor,您的代码示例将正常工作。

if __name__ == '__main__':
    tst = Test()
    rtn = tst.deferredChain()
    reactor.run()
    print "RTN: %s " % rtn

Twisted Treq 是一个构建在代理之上的有趣框架,它承诺为您提供 Python 请求,例如用于 Twisted 异步 HTTP 客户端的 API。

【讨论】:

  • 感谢@Pawel 的回答。但是这种方法还行不通。也许我的问题不清楚。我现在做了一些调整。需要从回调链中的函数执行获取请求并检查 http 返回码。根据此代码,我想从原始回调链中进行特定返回。我的难点是get请求的回调函数没有被调用。
【解决方案2】:

您正在同步调用 tst.deferredChain() 并尝试在其中读取 d.result ,这是不正确的。正确的解决方案是让它也返回一个 deferred 并附加一个回调。

【讨论】:

  • 嗨@pinturic!感谢您的回答。如果我理解得很好,我需要将函数 deferredChain() 的同步调用替换为另一个延迟对象的回调。我尝试使用以下代码执行此操作:defA = defer.Deferred()defA.addCallback(Test.deferredChain)defA.callback("success")rtn = defA.result 新行为似乎是一个循环,控制台没有响应。我不知道现在到底发生了什么。这是我的问题的正确解决方案吗?我忘记了什么?
猜你喜欢
  • 1970-01-01
  • 2017-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-01
  • 1970-01-01
  • 2013-09-22
  • 2013-01-08
相关资源
最近更新 更多