2016-07-14 74 views
1

所以我按照指南http://tavendo.com/blog/post/going-asynchronous-from-flask-to-twisted-klein/創建一個異步web服務。如何用python同時發送兩個請求

在我的代碼,我不得不將發出請求像

def query(text): 
    resp = yield treq.get("http://api.Iwanttoquery") 
    content = yield treq.content(resp) 
    returnValue(content) 

@inlineCallbacks 
def caller(): 
    output1 = yield query("one") 
    output2 = yield query("two") 

由於每個查詢到的API通常需要大約3秒,我當前的代碼,結果在6秒後回來的功能。我不知道是否有辦法同時發出兩個查詢,所以3秒後我可以得到output1和output2的內容?謝謝。

+0

您可以使用線程或找到一種方法將查詢合併到一個查詢中 – depperm

+0

您的「問題」是您正在使用「inlineCallbacks」(缺少更好的單詞)像同步代碼一樣行事。所以基本上''output1''必須先產生一個值,然後才能移動到''output2''。 –

回答

2

你需要做的是使用DeferredList而不是inlineCallbacks。基本上你提供了一個延期清單,每完成一次,就會執行一個最終的回調和所有延期的結果。

import treq 
from twisted.internet import defer, reactor 

def query(text): 
    get = treq.get('http://google.com') 
    get.addCallback(treq.content) 
    return get 

output1 = query('one') 
output2 = query('two') 

final = defer.DeferredList([output1, output2]) # wait for both queries to finish 
final.addCallback(print) # print the results from all the queries in the list 

reactor.run() 

每個query()功能將執行請求的同時,然後返回一個Deferred。這幾乎立即發生,所以基本上output1output2正在同時執行。然後在list中追加延期(即output1output2)並將其傳遞給DeferredList,該本身返回Deferred。最後,你添加一個回調到DeferredList做結果(在這種情況下,我只是打印它們)。這一切都沒有使用線程,這是我認爲最好的部分!希望這是有道理的,並請評論,如果沒有。

PS

如果您需要克萊恩進一步的幫助,我正在這裏改造的文檔https://github.com/notoriousno/klein-basics(希望我將做一個博客帖子的這些天)。請看看一些文檔(文件.rst)。我的無恥插頭現已結束:D