Dunaevlad
@Dunaevlad

Как поставить в очередь две функции?

import aiohttp
import asyncio


async def get_request(session, url):
    """Make GET request"""
    async with session.get(url) as response:
        return await response.json()


async def parse_json(response):
    """Parse JSON"""
    for outcomes in response:
        print(
            outcomes["payload"]["id"],
            outcomes["payload"]["name"],
        )


async def main():
    """Main function"""
      url = "https://www.example.com/api/"

    async with aiohttp.ClientSession() as session:

        task_0 = asyncio.create_task(get_request(session, url))
        response = await task_0
        task_1 = asyncio.create_task(parse_json(response))

        await asyncio.gather(task_0, task_1)


if __name__ == "__main__":
    asyncio.run(main())


В вышеуказанном коде, я ставлю в очередь функцию запроса и функцию парсера JSON.
А как мне сделать, если у меня будет 100 адресов?
Т.е. мне надо, что бы он делал запрос и парсил JSON, а не сначала запросы, затем парсер JSON, при этом из JSON берутся данные и добавляются в массив.

Я написал примерно, но не уверен, что это правильно =>
async def main():
    """Main function"""
    urls = [...]
    tasks = []
    async with aiohttp.ClientSession() as session:
        
        for url in urls:
              task = asyncio.create_task(get_request(session, url))
              tasks.append(task)

    r = await asyncio.gather(*tasks, return_exceptions=True)
    await parse_json(r)
            
  if __name__ == "__main__":
    asyncio.run(main())
  • Вопрос задан
  • 133 просмотра
Решения вопроса 1
Vindicar
@Vindicar
RTFM!
task_0 = asyncio.create_task(get_request(session, url))
        response = await task_0
        task_1 = asyncio.create_task(parse_json(response))

        await asyncio.gather(task_0, task_1)

Абсолютно бесполезный код. Ты дожидаешься (await) выполнения task_0, а потом пытаешься параллельно выполнить (gather) task_0 и task_1, хотя task_0 уже выполнена.
Более того, почему разбор JSON у тебя async, если он не делает вообще ничего асинхронного?
Просто сверни всё в одну функцию, и выполняй сотню её копий через gather().

async def handle_request(session, url):
    async with session.get(url) as response:
        data = await response.json()
    results = []
    for outcomes in data:
        results.append(
            (outcomes["payload"]["id"],
            outcomes["payload"]["name"],)
        )
    return results

А потом при вызове:
session = ...
urls = [ .................. ]
tasks = [handle_request(session, url) for url in urls] #набор невыполненных асинхронных задач
# планируем их выполнение "одновременно"
all_results = asyncio.gather(*tasks) #почитай про return_exceptions
for results in all_results:
    pass #тут уже работаешь с возвращённым значением
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы