2017-06-13 33 views
1

我對Python的等待和哈瓦的例子有所懷疑,它試圖使用await從未來的obj中獲取結果。我如何使用async/await來調用python3.6中的未來obj

import time 
import asyncio 
import time 
import random 
import threading 

db = { 
    "yzh": "pig", 
    "zhh": "big pig" 
} 
loop = asyncio.get_event_loop() 

def _get_redis(username, clb): 
    def foo():  
     data = db[username]  
     time.sleep(0.1) 
     print("start clb") 
     clb(data) 
    t1 = threading.Thread(target=foo) 
    t1.start() 


def get_redis(username): 
    print("start get redis") 
    myfuture = asyncio.Future() 
    def clb(result): 
     print("clb call") 
     myfuture.set_result(result) 

    _get_redis(username, clb) 
    return myfuture 

async def main(): 
    print("start main") 
    data = await get_redis("yzh") 
    print("data is {}".format(data)) 

loop.run_until_complete(asyncio.ensure_future(main())) 
loop.close() 

,我得到了一個沒有未來的結果輸出:

start main 
start get redis 
start clb 
clb call 

我應該怎麼用等待來獲得未來的結果,我試過很多次?謝謝你的幫助。

+1

我得到了答案。安排一個不同線程的回調,應該使用AbstractEventLoop.call_soon_threadsafe()方法。(https://docs.python.org/3/library/asyncio-dev.html) –

回答

1

正如您在您的評論說,你應該從一個線程中運行的回調ASYNCIO時使用loop.call_soon_threadsafe

loop.call_soon_threadsafe(myfuture.set_result, result) 

然而,從ASYNCIO調用同步功能,更好的辦法是使用loop.run_in_executor

def _get_redis(username): 
    time.sleep(0.1) 
    return db[username] 

async def get_redis(username): 
    return await loop.run_in_executor(None, _get_redis, username) 

這樣,您就不必處理期貨和線程安全的回調。

+0

非常感謝,非常感謝。 –

相關問題