我的代码需要什么 gen.sleep 来执行异步函数?

What my code needs a gen.sleep to execute a function async?

我根据 Python 的 Tornado 编写了以下代码:

def process_data(data):
    # To something

def handler(message):
    if message['type'] == 'message':
        data = message['data']
        IOLoop.current().spawn_callback(process_data, data)

async def main():
    redis_client = RedisClient(redis_conf)
    pubsub = redis_client.subscribe("CHANNEL", handler)

    async def fetch_messages():
        while True:
            pubsub.get_message()
            await gen.sleep(0.0001) 


    await fetch_messages()

if __name__ == "__main__":
    import logging
    logging.basicConfig()

    parse_command_line()

    tornado.web.Application(debug=options.debug)

    io_loop = ioloop.IOLoop.current()
    io_loop.run_sync(main)

根据上面的代码,我可以看到正在调用 process_data。但是,如果我删除 await gen.sleep(0.0001),则永远不会调用 process_data。有谁知道为什么?

IOLoop.spawn_callback(callback, *args, **kwargs)

Calls the given callback on the next IOLoop iteration.

如果你一直调用一些同步代码(while True 没有 await)你不会 return 控制事件循环并且事件循环不能迭代到执行回调。

await gen.sleep(0.0001) - 控制 return 到事件循环的地方,以便它可以做一些事情(比如执行回调)。

Tornado 对 return 控制事件循环有特殊的对象,例如你的情况 - gen.moment:

    while True:
        pubsub.get_message()
        await gen.moment

我没有使用 Tornado,但我打赌更好的是使用一些设计用于异步程序的 redis 客户端,see this answer