以aiohttp为例, 以下封装了一个aiohttp的网页请求。
from aiohttp import ClientSession
from asyncio import get_event_loop
from asyncio import ensure_future
from asyncio import gather
from functools import partial
async def aio_request(kwargs):
async with ClientSession() as session:
response = await session.request(**kwargs)
try:
context = await response.text(encoding='utf-8')
except UnicodeDecodeError:
context = await response.text(encoding='gbk')
return context
def callback_None(future):
print(future.result())
def callback(a, future):
print(future.result())
print(a)
那么问题来了,怎么拿到异步函数的返回值呢,以下抛出3种方法。
URL = 'http://toefl.koolearn.com/20160819/810320.html'
METHOD = 'get'
HEADERS = {
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Connection': 'keep-alive',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/77.0.3865.90 Safari/537.36',
}
REQUEST_INFORMATION = {
'url': URL,
'method': METHOD,
'headers': HEADERS,
}
loop = get_event_loop()
tasks = gather(*[ensure_future(aio_request(REQUEST_INFORMATION))])
tasks.add_done_callback(callback_None)
tasks.add_done_callback(partial(callback, '22'))
loop.run_until_complete(tasks)
print(tasks.result())
tasks.add_done_callback(callback_None)
方法一,通过tasks的函数add_done_callback函数, 传入你所写的回调函数,每当有函数跑完的await的地方,就会调用回调函数,而future则是你一开始创建的future对象,所以打印future.result()就能看到,是你想要的到的返回值
tasks.add_done_callback(partial(callback, ‘22’))
方法二,通过定义回调函数,当你想要传递参数的时候,也可以这样写,从functools导入partial, 因为partial填入的参数位置是第一位,所以要将future放在最后就好了,这样就可以解决传参问题了
tasks.result()
方法三,从tasks拿到加入gather的所有函数的返回值
闭包
为什么要说闭包呢,因为回调函数的原理类似于闭包。
def add(a, b):
def show(result):
print(result)
return show(result)
show就相当于一个闭包,是内置的一种方法,当要传入一个自定义函数的时候就可以这样写
def add(a, b, func==None):
def show(result):
print(result)
if not func:
return show(result)
else:
return func(result)
如果没传入函数就执行内置闭包函数,否则执行外部提供的函数。这就有点像回调函数的味道了是把。
因为有些情况下,调用函数不能直接拿到返回值,例如异步的情况下,但因为每个用户想要间接拿到返回值的方式不一样,有的用queue有的用redis有的直接print,用闭包函数就可以通过传入一个自定义回调函数,就可以兼容用户的不同需求。有了这种情况后,用户就不用进去源码查看大堆的代码找到代码位置,再去定义闭包函数了。