1、为什么要用异步编程

所谓同步,是指操作一个接一个地执行,下一个操作必须等上一个操作执行完成之后才能开始执行;而异步是指不同操作间可以相互交替执行,如果其中地某个操作被堵塞,程序并不会等待,而是会找出可执行的操作继续执行,所以当存在大量请求的时候,异步编程的响应速度会存在巨大差别。

2、异步编程小案例

请看如下代码:

import asyncio
import aiohttp
import time
import requests

sites = [
    'https://www.flvcd.com/url.php#sohu',
    'https://www.flvcd.com/url.php#letv',
    'https://www.flvcd.com/url.php#56',
    'https://www.flvcd.com/url.php#yinyuetai',
    'https://www.flvcd.com/parse.php?kw=http://open.163.com/movie/2011/9/I/7/M7CTDM4AF_M7VLT57I7.html',
    'https://www.flvcd.com/parse.php?flag=&kw=http://weibo.com/p/230444275371ca2a5d0b4799dfc23ab3a98d61',
    'https://www.flvcd.com/parse.php?flag=&kw=http://v.pps.tv/play_323QCL.html',
    'https://www.flvcd.com/parse.php?flag=&kw=http%3A%2F%2Fv.ifeng.com%2Fnews%2Fworld%2F200811%2Fa5a067f8-90d5-4368-a717-d1e70543dee1.shtml',
    'https://www.flvcd.com/parse.php?kw=http://www.taihaitv.cn/20111118/108849.shtml',
    'https://www.flvcd.com/parse.php?kw=http://tv.v1.cn/mlszy/2011-3-4/1299131550159v.shtml',
    'https://www.flvcd.com/parse.php?kw=http://www.hualu5.com/t/tyzhn/7120.html',
    'https://www.flvcd.com/parse.php?kw=http://msn.v1.cn/shehui/sh/2010-12-9/1291856176999v.shtml'
]




async def download_one(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as resp:
            print('Read {} from {}'.format(resp.content_length, url))


async def download_all(sites):
    tasks = [asyncio.ensure_future(download_one(site)) for site in sites]
    await asyncio.gather(*tasks)


def _download_one(url):
    requests.get(url)
def _download_all(sites):
    for site in sites:
        _download_one(site)

def main():

    start_time = time.perf_counter()

    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(download_all(sites))
    finally:
        loop.close()
    end_time = time.perf_counter()
    print('异步下载 {} sites in {} seconds'.format(len(sites), end_time - start_time))

def _main():
    start_time = time.perf_counter()
    _download_all(sites)
    end_time = time.perf_counter()
    print('同步下载 {} sites in {} seconds'.format(len(sites), end_time - start_time))

if __name__ == '__main__':
    main()
    _main()

3、结果分析

Read 9249 from https://www.flvcd.com/url.php#56
Read 9249 from https://www.flvcd.com/url.php#sohu
Read 9249 from https://www.flvcd.com/url.php#yinyuetai
Read 9249 from https://www.flvcd.com/url.php#letv
Read 4444 from https://www.flvcd.com/parse.php?kw=http://open.163.com/movie/2011/9/I/7/M7CTDM4AF_M7VLT57I7.html
Read 4551 from https://www.flvcd.com/parse.php?flag=&kw=http%3A%2F%2Fv.ifeng.com%2Fnews%2Fworld%2F200811%2Fa5a067f8-90d5-4368-a717-d1e70543dee1.shtml
Read 3059 from https://www.flvcd.com/parse.php?kw=http://www.taihaitv.cn/20111118/108849.shtml
Read 2945 from https://www.flvcd.com/parse.php?flag=&kw=http://weibo.com/p/230444275371ca2a5d0b4799dfc23ab3a98d61
Read 2945 from https://www.flvcd.com/parse.php?flag=&kw=http://v.pps.tv/play_323QCL.html
Read 2945 from https://www.flvcd.com/parse.php?kw=http://msn.v1.cn/shehui/sh/2010-12-9/1291856176999v.shtml
Read 2945 from https://www.flvcd.com/parse.php?kw=http://tv.v1.cn/mlszy/2011-3-4/1299131550159v.shtml
Read 2945 from https://www.flvcd.com/parse.php?kw=http://www.hualu5.com/t/tyzhn/7120.html
异步下载 12 sites in 25.7260843 seconds
同步下载 12 sites in 64.8164072 seconds

很明显,当上面存在十几个链接的时候,两者的时间上相差了大概3倍,如果链接特别多,可能还有更大差别,所以,平时要注意异步编程的使用。