我使用asyncio
和漂亮的aiohttp
。主要的想法是我向服务器发出请求(它返回链接),然后我想从并行中的所有链接下载文件(类似于example)。
代码:
import aiohttp
import asyncio
@asyncio.coroutine
def downloader(file):
print('Download', file['title'])
yield from asyncio.sleep(1.0) # some actions to download
print('OK', file['title'])
def run():
r = yield from aiohttp.request('get', 'my_url.com', True))
raw = yield from r.json()
tasks = []
for file in raw['files']:
tasks.append(asyncio.async(downloader(file)))
asyncio.wait(tasks)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
但是,当我尝试运行它时,我有很多“下载...”输出和
Task was destroyed but it is pending!
没有'OK + filename'。
我该如何解决?
答案 0 :(得分:12)
您忘记yield from
对asyncio.wait
的通话了。你也可能有错误的缩进;您只想在遍历整个raw['files']
列表后运行它。以下是修复了两个错误的完整示例:
import aiohttp
import asyncio
@asyncio.coroutine
def downloader(file):
print('Download', file['title'])
yield from asyncio.sleep(1.0) # some actions to download
print('OK', file['title'])
@asyncio.coroutine
def run():
r = yield from aiohttp.request('get', 'my_url.com', True))
raw = yield from r.json()
tasks = []
for file in raw['files']:
tasks.append(asyncio.async(downloader(file)))
yield from asyncio.wait(tasks)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
如果没有调用yield from
,run
会在您遍历整个文件列表后立即退出,这将意味着您的脚本退出,导致一大堆未完成的downloader
要销毁的任务,以及你看到要显示的警告。