對於更復雜的背景任務,像芹菜是最好的選擇。但對於更簡單的用例,您需要的是threading
模塊。
請看下面的例子:
from flask import Flask
from time import sleep
app = Flask(__name__)
def slow_function(some_object):
sleep(5)
print(some_object)
@app.route('/')
def index():
some_object = 'This is a test'
slow_function(some_object)
return 'hello'
if __name__ == '__main__':
app.run()
在這裏,我們創建了一個功能,slow_function()
在返回前睡五秒鐘。當我們在路由功能中調用它時,它會阻止頁面加載。運行該示例,然後在瀏覽器中點擊http://127.0.0.1:5000,然後在加載之前,您會看到頁面等待五秒鐘,然後在終端中打印測試消息。
我們想要做的是將slow_function()
置於不同的線程。隨着只是一對夫婦的代碼其它行,我們可以使用threading
模塊給這個函數的執行分離出在不同的線程:
from flask import Flask
from time import sleep
from threading import Thread
app = Flask(__name__)
def slow_function(some_object):
sleep(5)
print(some_object)
@app.route('/')
def index():
some_object = 'This is a test'
thr = Thread(target=slow_function, args=[some_object])
thr.start()
return 'hello'
if __name__ == '__main__':
app.run()
我們在這裏所做的很簡單。我們正在創建一個Thread
的新實例,並將它傳遞給兩件事:target
(這是我們想要運行的函數)和args
(即要傳遞給目標函數的參數)。請注意,slow_function
上沒有括號,因爲我們不是,它運行的是它 - 函數是對象,所以我們將函數本身傳遞給Thread
。至於args
,這總是期待一個列表。即使你只有一個參數,將其包裝在一個列表中,以便args
得到它所期望的。
隨着我們的線程準備就緒,thr.start()
執行它。在你的瀏覽器中運行這個例子,你會注意到索引路由現在立即加載。但再等五秒鐘,果然,測試信息將打印在您的終端中。
現在,我們可以在這裏停下來 - 但至少在我看來,實際上在線路本身內部存在這個線程代碼有點麻煩。如果你需要在另一條路線或不同的環境中調用這個函數呢?最好把它分成它自己的功能。你可以將線程行爲本身作爲慢函數的一部分,或者你可以創建一個「包裝器」函數 - 你採取的方法很大程度上取決於你在做什麼以及你的需求。
讓我們創建一個包裝函數,看看它是什麼樣子:
from flask import Flask
from time import sleep
from threading import Thread
app = Flask(__name__)
def slow_function(some_object):
sleep(5)
print(some_object)
def async_slow_function(some_object):
thr = Thread(target=slow_function, args=[some_object])
thr.start()
return thr
@app.route('/')
def index():
some_object = 'This is a test'
async_slow_function(some_object)
return 'hello'
if __name__ == '__main__':
app.run()
的async_slow_function()
功能做得非常正是我們所做的事情 - 它只是有點整潔了。你可以在任何路徑上調用它,而不必重新重寫你的線程邏輯。你會注意到這個函數實際上返回了線程 - 我們不需要需要對於這個例子,但是以後可能還想用其他的方法來處理這個線程,所以如果你使用線程對象需要它。
我會用'celery'來進行異步任務管理。 http://flask.pocoo.org/docs/0.12/patterns/celery/ –
Celery的一個不太乾淨的替代方法是爲該方法提供一個路徑(在@ decorator中),並在調查頁面調用ajax請求時調用它被加載。 –