为什么 Twisted 的 inlineCallbacks return 是一个“延迟”对象?

Why does Twisted's inlineCallbacks return a "Deferred' object?

我正在尝试了解 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. return 延迟对象的真正需求是什么,即谁在使用它?
  2. 谁用最终值调用它?
  3. 如果不 returned 会怎样?

repl 中,我不明白为什么我需要这个 return 值。我的根本问题似乎是因为我仍然没有考虑这些功能的消费者?

所以让我们使用一些 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

What is the real need to return a Deferred object i.e who the consumes it?

触发这种内联回调函数的代码可以在这里注册它的post处理动作。一个示例可能是:d.addCallback(handle_http_response).

Who invokes it with the final value?

内联回调装饰器机制可以做到这一点 internally。它会在生成器引发 StopIteration 时触发此 Deferred,即当生成器最终 return 为外部世界编辑了一些东西。相反,yielded 值仅在 generator.

内部使用

What happens if it not returned?

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