为什么Twisted的inlineCallbacks返回一个“Deferred”对象?

时间:2017-01-04 11:55:44

标签: python twisted

我试图了解inlineCallbacks如何使异步代码看起来像同步代码一样工作。我在这里使用Twisted's实现作为参考。

正常功能:输入→输出

inlineCallbacks装饰生成器功能:输入→延迟

它返回一个Deferred,即一个可以在callback注册的对象。

from twisted.internet import defer

intermediate_deferred = None

@defer.inlineCallbacks
def example():
    global intermediate_deferred
    print("Started")
    intermediate_deferred = defer.Deferred()
    result = yield intermediate_deferred
    print("Resuming for the first time with %s" % result)
    intermediate_deferred = defer.Deferred()
    result = yield intermediate_deferred
    print("Resuming for the second time with %s" % result)

generator_deferred = example()
intermediate_deferred.callback("One")
intermediate_deferred.callback("Two")
  1. 返回Deferred对象的真正需要是什么,即消耗它的人?
  2. 谁用最终值调用它?
  3. 如果没有返回会怎么样?
  4. repl我不明白为什么我需要这个返回值。我的基本问题似乎是因为我仍然没有考虑这些功能的消费者?

    因此,让我们采取一些Web框架并想象代码应该如何:

    # Assume it returns 'example' function object.
    function_to_call = get_routing_function(request)
    d = function_to_call()
    # But who takes care of calling it back? The Event Loop has to do that?
    # So the Event Loop has one important job of monitoring and calling back
    # such Deferred's to complete the full cycle?
    d.addCallback(handle_http_response)
    
    @defer.inlineCallbacks
    def get_user_details(user_idn):
        result = yield get_user_details_from_cache(user_idn)
        if not result:
           result = yield get_user_details_from_db(user_idn)
        result = post_process_user_details(user_idn)
        return result
    

1 个答案:

答案 0 :(得分:0)

  

返回Deferred对象的真正需要是什么,即谁   消耗它?

触发此类内联回调函数的代码可以在此处注册其后处理操作。一个例子可能是:d.addCallback(handle_http_response)

  

谁用最终值调用它?

内联回调装饰器机制执行此操作internally。当生成器引发Deferred时,即当生成器最终StopIteration为外部世界编写内容时,它会触发此return。相反,yield ed值仅在generator内部使用。

  

如果没有返回会怎么样?

您只能将这些生成器功能用于副作用,即您无法对这些功能的输出值执行任何操作。