我正在尝试包装一个异步函数,以便可以在不将asyncio导入某些文件的情况下使用它。最终目标是使用异步函数,但能够正常调用它们并获取结果。
如何从回调函数printing(task)
访问结果并将其用作我的make_task(x)
函数的返回?
MWE:
#!/usr/bin/env python3.7
import asyncio
loop = asyncio.get_event_loop()
def make_task(x): # Can be used without asyncio
task = loop.create_task(my_async(x))
task.add_done_callback(printing)
# return to get the
def printing(task):
print('sleep done: %s' % task.done())
print('results: %s' % task.result())
return task.result() # How can i access this return?
async def my_async(x): # Handeling the actual async running
print('Starting my async')
res = await my_sleep(x)
return res # The value I want to ultimately use in the real callback
async def my_sleep(x):
print('starting sleep for %d' % x)
await asyncio.sleep(x)
return x**2
async def my_coro(*coro):
return await asyncio.gather(*coro)
val1 = make_task(4)
val2 = make_task(5)
loop.run_until_complete(my_coro(asyncio.sleep(6)))
print(val1)
print(val2)
答案 0 :(得分:0)
您可以使printing
为协程,而await
为原始协程,例如my_async
,而不使用回调。 make_task
然后可以从printing(my_async(...))
中创建任务,这将使printing
的返回值可用作任务结果。换句话说,要从printing
中返回一个值,只需-将其返回。
例如,如果您这样定义make_task
和printing
,而使程序的其余部分保持不变:
def make_task(x):
task = loop.create_task(printing(my_async(x)))
return task
async def printing(coro):
coro_result = await coro
print('sleep done')
print('results: %s' % coro_result)
return coro_result
结果输出为:
Starting my async
starting sleep for 4
Starting my async
starting sleep for 5
sleep done
results: 16
sleep done
results: 25
<Task finished coro=<printing() done, defined at result1.py:11> result=16>
<Task finished coro=<printing() done, defined at result1.py:11> result=25>
答案 1 :(得分:0)
如果我正确理解,您想使用异步函数,但不想在顶级代码中编写async
/ await
。
如果是这种情况,恐怕asyncio
无法实现。 asyncio
希望您在发生异步操作的任何地方编写async
/ await
,这是有意的:强制明确标记可能的上下文切换的位置是asyncio
的一种抗击方式与并发相关的问题(否则很难解决)。阅读this answer了解更多信息。
如果您仍然希望拥有异步内容并“像往常一样使用”代码,请查看gevent之类的替代解决方案。