requests
不支持asyncio
。如果您想进行真正的异步执行,则必须查看aiohttp 之类的库或询问
您的集合应该在卸载到任务之前构建,因此您甚至不执行重复项,而不是简化结果。
就其requests
本身而言,您可以回退到哪个将在ThreadPoolExecutorrun_in_executor
中执行您的请求,因此不是真正的异步 I/O:
import asyncio
import time
from requests import exceptions, get
def _url_exists(url):
try:
r = get(url, timeout=10)
except (exceptions.ConnectionError, exceptions.ConnectTimeout):
return False
else:
return r.status_code is 200
async def _remove_unexisting_urls(l, r):
# making a set from the list before passing it to the futures
# so we just have three tasks instead of nine
futures = [l.run_in_executor(None, _url_exists, url) for url in set(r)]
return [await f for f in futures]
rows = [ # added some dupes
'http://example.com/',
'http://example.com/',
'http://example.com/',
'http://example.org/',
'http://example.org/',
'http://example.org/',
'http://foo.org/',
'http://foo.org/',
'http://foo.org/',
]
loop = asyncio.get_event_loop()
print(time.time())
result = loop.run_until_complete(_remove_unexisting_urls(loop, rows))
print(time.time())
print(result)
输出
1537266974.403686
1537266986.6789136
[False, False, False]
如您所见,初始化线程池会产生损失,在这种情况下约为 2.3 秒。但是,考虑到这三个任务中的每一个都运行了十秒直到我的机器超时(我的 IDE 不允许通过代理),所以总体上 12 秒的执行时间看起来相当并发。