我最近尝试使用扭曲的框架进行一些异步编程任务。我不太明白的一件事是如何包装一个带回调函数的函数并使它成为一个返回延迟对象的函数?
例如,如果我有如下函数:
def registerCallbackForData(callback):
pass # this is a function that I do not control, some library code
现在我使用它的方式就是注册一个回调。但是我希望能够将它合并到扭曲的框架中,可能会返回一个延迟对象并稍后使用reactor.run()。这可能吗?
答案 0 :(得分:2)
def convert_callback_to_deferred(f):
def g():
d = Deferred()
d.addCallback(callback)
f(d.callback)
return d
return g
from somelib import registerCallbackForData
getSomeDeferredForData = convert_callback_to_deferred(registerCallbackForData)
d = getSomeDeferredForData()
d.addCallback(...)
...
但是,请记住,Deferred
最多只能产生一个结果。如果registerCallbackForData(cb)
导致cb
被多次调用,那么第二次及以下调用的数据就无处可去。只有拥有最多一次的事件源才有意义将其转换为Deferred
界面。
答案 1 :(得分:-1)
defer.maybeDeferred将包含一个阻塞函数调用以返回延迟。如果您希望呼叫是非阻止的,则可以使用threads.deferToThread。
您可以通过切换注释掉的电话来查看差异:
import time
from twisted.internet import reactor, defer, threads
def foo():
print "going to sleep"
time.sleep(1)
print "woke up"
return "a result"
def show_result_and_stop_reactor(result):
print "got result: %s, stopping the reactor" % result
reactor.stop()
print "making the deferred"
d = defer.maybeDeferred(foo)
# d = threads.deferToThread(foo)
print "adding the callback"
d.addCallback(show_result_and_stop_reactor)
print "running the reactor"
reactor.run()