异步回调--day36

"""
----异步回调----

异步任务使用场景
爬虫
1.从目标站点下载网页数据 本质就是HTML格式字符串
2.用re从字符串中提取出你需要的数据

什么是回调(函数)
a 交给 b一个任务 b在执行完成后回过头调用了a的一个函数 就称之为回调

为什么需要回调函数?
需要获取异步任务的结果,但是又不应该阻塞(降低效率)
高效的获取任务结果
(像生产者与消费者,生产者生产了产品后,通知消费者过来消费,消费者不需要一直等待生产者)

通常异步任务都会和回调函数一起使用
使用方式:
使用add_done_callback函数()给Future对象绑定一个回调函数

注意:在多进程中回调函数 是交给主进程来执行 而在多线程中 回调函数是谁有空谁执行(不是主线程)
"""
#-----进程中使用异步回调来处理结果----

import requests, re, os
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
from threading import current_thread

# 请求下载一个网业的数据
response = requests.get("https://www.baidu.com")

# 下载网站的数据,转换格式
htm = response.content.decode("utf-8")

# 用正则表达式取出网页里面的所有链接
# print(re.findall("href=.*?com",htm))

def get_data(url):
    print("%s 正在请求%s" % (os.getpid(), url))
    # 下载网址的内容
    response = requests.get(url)
    print("%s 请求%s成功" % (os.getpid(), url))
    # 返回出去----1
    return response


def parser(obj):
    # 获得上一段代码的返回值
    res = obj.result()
    htm = res.content.decode("utf-8")
    ls = re.findall("href=.*?com", htm)
    print("%s解析完成! 共%s个连接" % (os.getpid(), len(ls)))


# 不加报错
if __name__ == '__main__':
    urls = ["https://www.baidu.com",
            "https://www.sina.com",
            "https://www.tmall.com",
            "https://www.taobao.com",
            "https://www.jd.com",
            "https://www.python.org",
            "https://www.apple.com"]
    # 用一个进程池  来开启进程
    pool = ProcessPoolExecutor(3)

    for i in urls:
        # 循环取出urls 中的网址 交给进程池  得到执行完后的返回值
        obj = pool.submit(get_data, i)

        # res = obj.result() # 会把任务变成串行
        # parser(res)

        # 上一段代码执行完成后 会得到通知,继续执行下一段代码
        obj.add_done_callback(parser)
# ----线程池中使用异步回调----

import requests, re, os
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
from threading import current_thread

def get_data(url):
    # current_thread().name  获取执行线程的名字
    print("%s 正在请求%s" % (current_thread().name, url))
    response = requests.get(url)
    print("%s 请求%s成功" % (current_thread().name, url))
    return response


def parser(obj):
    res = obj.result()
    htm = res.content.decode("utf-8")
    ls = re.findall("href=.*?com", htm)
    print("%s解析完成! 共%s个连接" % (current_thread().name,len(ls)))

if __name__ == '__main__':
    urls = ["https://www.baidu.com",
            "https://www.tmall.com",
            "https://www.taobao.com",
            "https://www.jd.com",
            "https://www.python.org",
            "https://www.apple.com"]
    pool = ThreadPoolExecutor(3)

    for i in urls:
        # 循环取出urls 中的网址 交给线程池  得到执行完后的返回值
        obj = pool.submit(get_data, i)

        # res = obj.result() # 会把任务变成串行
        # parser(res)

        # 上一段代码执行完成后 会得到通知,继续执行下一段代码
        obj.add_done_callback(parser)

 



posted @ 2019-01-04 17:29  WenChen-0o0  阅读(107)  评论(0编辑  收藏  举报