要使您的代码异步,您需要使用此处描述的Twisted Deferreds。Deferreds 为您提供了一个用于异步代码执行的 API,它们允许您将回调附加到您的函数,并且它们在由 reactor 对象管理的 Twisted 事件循环中执行代码。
在您的情况下,我看到了两种使用 Deferreds 的潜在方法。
1)在后台执行任务reactor.callLater()
如果dostuff
处理程序不关心结果,这没关系。您可以使用reactor.callLater()。这样,您的 async 函数将在您从doStuff
.
所以是这样的:
from klein import run, route, Klein
from twisted.internet import defer, task, reactor
import os
app = Klein()
def logging(data):
ofile = open("file", "w")
ofile.write(data)
result = os.system("ls")
print(result)
@route('/')
def dostuff(request):
reactor.callLater(0, logging, "some data")
print("check!")
return b'Hello, world!'
run("localhost", 8080)
此代码的事件顺序如下,首先打印“check”,然后返回“hello world”响应,最后异步调用成功并打印 running 的结果os.system()
。
2016-08-11 08:52:33+0200 [-] check!
2016-08-11 08:52:33+0200 [-] "127.0.0.1" - - [11/Aug/2016:06:52:32 +0000] "GET / HTTP/1.1" 200 13 "-" "curl/7.35.0"
a.py file
2)在后台执行任务并获得结果task.deferLater()
如果您关心“日志记录”功能的结果,您还可以将回调附加到该对象并使用twisted.internet.task API。如果你想这样,你需要重构你的处理程序才能像这样工作
@route('/')
def dostuff(request):
def the_end(result):
print("executed at the end with result: {}".format(result))
dfd = task.deferLater(reactor, 0, logging, "some data")
dfd.addCallback(the_end)
print("check!")
return b'Hello, world!'
这种方式的事件顺序将与上述相同,但the_end
函数将在logging
函数完成后最后执行。
2016-08-11 08:59:24+0200 [-] check!
2016-08-11 08:59:24+0200 [-] "127.0.0.1" - - [11/Aug/2016:06:59:23 +0000] "GET / HTTP/1.1" 200 13 "-" "curl/7.35.0"
a.py file
2016-08-11 08:59:24+0200 [-] executed at the end with result: some result