![](/img/trans.png)
[英]how to return value from tornado.ioloop.IOLoop instance add_future method
[英]How to return a value from a coroutine that was run with Tornado's IOLoop?
假設我有這個異步函數(Python 3.5)
async def func():
return '42'
我有一個Tornado I / O循環,正在尋找一種執行它的方法。
import tornado.ioloop
ioloop = tornado.ioloop.IOLoop.current()
ioloop.start()
我可以只使用IOLoop.add_callback(func)
,但我也需要一個返回值。
關於從中獲取返回值需要什么的任何想法?
編輯
func
coroutine方法實際上接收一個字符串,並將其發送到服務器,接收響應,對其進行適當的解包並返回一個數據元組。
從常規(非異步)方法中調用該方法,該方法根據其參數組裝字符串,並應該獲得響應並將數據返回給調用方。
IO循環是一個類變量(可通過self.
訪問self.
)
這是一個例子:
def register(self, arg1, arg2):
# process args here
ret_value = self.ioloop.add_callback(func, arg1, arg2)
# The above line is incorrect code, just for the idea
return ret_value
第二編輯
這是引發AssertionError的代碼部分:
async def _send(self, arg1):
self.ws.write_message(arg1)
resp = await self.ws.read_message()
return resp
def callback(self, future):
print('future', future.result())
def register(self, arg1):
future = self._send(arg1)
self.ioloop.add_future(future, self.callback)
我使用__init__
類中的PeriodicCallback開始執行register
。
register
方法中的變量future
包含<coroutine object Client._send at 0xb652c41c>
並且只有在is_future
給出的是concurrent.futures.Future
tornado.concurrent.Future
或tornado.concurrent.Future
的實例時, is_future
檢查才會通過
兩種選擇:使register
協程,或在回調中接收func
的返回值。
選項一:
async def register(self, arg1, arg2):
ret_value = await func(arg1, arg2)
return ret_value
選項二:
def callback(future):
try:
ret_value = future.result()
# Do something with ret_value here.
except Exception as exc:
# Log the exception or something.
print(exc)
def register(self, arg1, arg2):
future = func(arg1, arg2)
self.ioloop.add_future(future, callback)
顯然,選項二很尷尬,因為您不能在原始register
函數中使用ret_value。 我會選擇一種, register
一個協程。 然后, register
調用者必須一直是協程,一直到調用堆棧。
那是異步編程的一個鐵律:為了通過網絡進行通信,您的函數必須是執行yield
或await
的協程,或者您必須注冊一個回調並退出當前函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.