9

我用asyncio又漂亮aiohttp。主要思想是我向服务器发出请求(它返回链接),然后我想从所有链接并行下载文件(类似于示例)。

代码:

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 +文件名'无关。

我该如何解决?

4

1 回答 1

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任务被销毁,并显示您看到的警告。

于 2015-03-27T18:33:31.763 回答