我的代码需要什么 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。
我根据 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。