【问题标题】:how can i use async/await to call Future obj in python3.6我如何使用 async/await 在 python3.6 中调用 Future obj
【发布时间】:2017-11-15 15:23:36
【问题描述】:

我怀疑 Python 的 await 和 hava 一个例子,它尝试使用 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

我应该如何使用 await 来获得未来的结果?我尝试了很多次。感谢您的帮助。

【问题讨论】:

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


【解决方案1】:

正如您在评论中所说,从线程运行异步回调时应该使用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)

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-04
    • 2020-09-23
    • 1970-01-01
    • 1970-01-01
    • 2022-11-18
    • 1970-01-01
    • 2019-07-20
    • 2021-10-10
    相关资源
    最近更新 更多