Можно ли запустить асинхронный скрипт Python в стиле машинописи - PullRequest
0 голосов
/ 31 мая 2019

На данный момент у меня есть скрипт на python, который отправляет http-запрос в микросервис. Запрос занимает 3 секунды в среднем.

Это мой сценарий на языке Python в обобщенном виде.

def main():
  response = request_to_MS(url)

  # This process does not need the response of the microservice.
  some_process()

  # This is where i actually need a response from the microservice
  do_something_with_response(response)


main()

Я бы хотел, чтобы мой сценарий мог продолжить работу с кодом и позже ждать ответа на запрос, похожий на машинопись.

/**
 * I'd like to write this kind of code in python.
 */
function get_data(): Promise<string>{
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('This is resolved');
    })
  })
}

async function main(){
  const data = get_data();
  console.log('Data variable stores my promise ', data);
  // Some process
  [1, 2, 3, 4, 5, 6 ,7 ,8].forEach((x: number) => console.log(x));
  // I need the promise value here
  console.log('En el await', (await data).length)
}


void main();

В основном я ищу то, что время, необходимое для завершения выполнения процесса, и время отклика микросервиса перекрываются, что позволяет в целом улучшить время отклика.

1 Ответ

0 голосов
/ 31 мая 2019

Сделать request_to_MS(url) подпрограммой async def, запланировать ее как задачу с помощью response = asyncio.create_task(request_to_MS(url)).

Это начнет выполняться. Теперь вы можете продолжить запуск some_process(). Когда вам нужно response, просто сделайте

do_something_with_response(await response)

edit: вышеописанное будет работать только в том случае, если main также является async def, так как вы можете использовать await s только в асинхронной функции. Вместо того, чтобы звонить main(), звоните asyncio.run(main()).

Итого:

async def request_to_MS(url):
    await asyncio.sleep(3)
    return 'some internet data'

async def main():
    response = asyncio.create_task(request_to_MS(url))
    # response is now a Task

    some_process()

    # if response isn't done running yet, this line will block until it is
    do_something_with_response(await response)

asyncio.run(main())

Важное предостережение: some_process не обязательно должно быть сопрограммой, но если это блокирующая функция (либо ЦП, либо IO), она никогда не даст никаких циклов для запуска response. Если он блокируется через IO, подумайте о том, чтобы сделать его сопрограммой. Если нет никакой асинхронной поддержки для каких-либо низкоуровневых операций ввода-вывода, которые он выполняет, или если он связан с процессором, рассмотрите возможность использования run_in_executor * asyncio .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...