我试图了解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")
在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
答案 0 :(得分:0)
返回
Deferred
对象的真正需要是什么,即谁 消耗它?
触发此类内联回调函数的代码可以在此处注册其后处理操作。一个例子可能是:d.addCallback(handle_http_response)
。
谁用最终值调用它?
内联回调装饰器机制执行此操作internally。当生成器引发Deferred
时,即当生成器最终StopIteration
为外部世界编写内容时,它会触发此return
。相反,yield
ed值仅在generator
内部使用。
如果没有返回会怎么样?
您只能将这些生成器功能用于副作用,即您无法对这些功能的输出值执行任何操作。