2016-04-24 81 views
0

所以,我只是想換我周圍的異步編程頭(特別是龍捲風框架),我想我會從基礎開始:調用「等待」兩個協程:爲什麼兩個連續的協程(異步函數)並行執行?

from tornado.ioloop import IOLoop 
from tornado.web import Application, url, RequestHandler 
from tornado.gen import sleep 

class TestHandler(RequestHandler):  
    async def get(self): 
     f1 = await self.test("f1") 
     f2 = await self.test("f2") 
     self.write(f1 + " " + f2) 

    async def test(self, msg): 
     for i in range(5): 
      print(i) 
      await sleep(1) # this is tornado's async sleep 
     return msg 

app = Application([url(r'/', TestHandler)], debug=True) 
app.listen(8080) 
ioloop = IOLoop.current() 
ioloop.start() 

的然而,問題是,當我在瀏覽器中點擊localhost:8080,並且在我的Python控制檯盯着,我沒有看到的0 1 2 3 4 2個交織序列,但兩個連續的序列......

我讀過的龍捲風FAQ一遍又一遍,似乎無法理解我做錯了什麼。

回答

2

這將運行f1,等待它完成,然後運行f2

f1 = await self.test("f1") 
    f2 = await self.test("f2") 

並行運行的東西,你不能await開始前一秒第一個。要做到這一點,最簡單的方法是做他們兩個在一個await

f1, f2 = await tornado.gen.multi(self.test("f1"), self.test("f2")) 

或者在先進的情況下,你就可以開始f1無需等待它,然後回來以後等待它:

f1_future = tornado.gen.convert_yielded(self.test("f1")) 
f2_future = tornado.gen.convert_yielded(self.test("f2")) 
f1 = await f1_future 
f2 = await f2_future 
+0

第二個代碼塊(期待已久)不能同時運行......我誤解了你,它不應該被期望嗎? – StevieP

+0

啊,你說得對。這種模式使用'@ gen.coroutine'工作,但'async def'函數直到某些「等待」它們纔開始。 –

+0

你介意解釋最佳實踐嗎?看起來Tornado和'asyncio'(特別是'async' /'await')並沒有真正的配合。我們應該如何去編寫/裝飾異步代碼(因爲我們想要使用Tornado)? – StevieP