2017-06-13 28 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

非常感谢,非常感谢。 –

相关问题