我如何使用async / await在python3.6中调用Future obj

时间:2017-06-13 17:56:52

标签: async-await python-asyncio python-3.6

我怀疑Python等待并且有一个例子,它试图使用await从未来的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 个答案:

答案 0 :(得分: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)

这样,您就不必处理期货和线程安全的回调。