met*_*rsk 4 python http python-3.x python-asyncio aiohttp
我有以下功能正常,但由于某种原因,请求似乎是同步执行,而不是异步.
我现在的假设是,由于for record in recordsmain函数中的for循环,这种情况正在发生,但我不知道如何更改它以便请求可以执行异步.如果不是这样,我还需要改变什么呢?
async def do_request(query_string):
base_url = 'https://maps.googleapis.com/maps/api/place/textsearch/json?'
params = {'key': google_api_key,
'query': query_string}
async with aiohttp.ClientSession() as session:
async with session.request('GET', base_url, params=params) as resp:
return resp
async def main():
create_database_and_tables()
records = prep_sample_data()[:100]
for record in records:
r = Record(record)
if not r.is_valid:
continue
query_string = r.generate_query_string()
resp = await do_request(query_string)
print("NOW WRITE TO DATABASE")
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Run Code Online (Sandbox Code Playgroud)
您正在等待单独的do_request()呼叫.而不是直接等待它们(在协程完成之前阻塞它们),使用该asyncio.gather()函数让事件循环同时运行它们:
async def main():
create_database_and_tables()
records = prep_sample_data()[:100]
requests = []
for record in records:
r = Record(record)
if not r.is_valid:
continue
query_string = r.generate_query_string()
requests.append(do_request(query_string))
for resp in asyncio.gather(*requests):
print("NOW WRITE TO DATABASE")
Run Code Online (Sandbox Code Playgroud)
的asyncio.gather()返回值是所有的协程返回,在你通过他们的相同顺序的结果列表gather()功能.
如果您需要原始记录来处理响应,您可以通过几种不同的方式配对记录和查询字符串:
zip()在处理响应时再次使用它们进行配对您还可以将响应处理混合到聚集的协程中; 一个记录,产生查询字符串,等待do_request,然后在响应准备好时将结果存储在数据库中.
换句话说,将你需要连续发生的工作分成协同程序并收集它们.