简体   繁体   English

如何在后台运行任务时从异步 function 返回值?

[英]How to return a value from an async function while runing the task in the background?

[edit] Python 3.6 [编辑] Python 3.6

There is a function:有一个function:

def main(request):
    do_something() // task takes some days
    responce = {'status': 'started!'}
    return responce

I need it to return a responce right after do_something() started and NOT waiting for do_something() to be finished.我需要它在 do_something() 开始后立即返回响应,而不是等待 do_something() 完成。 I have already tried this:我已经尝试过这个:

def main(request):
    Thread(target=do_something).start()
    responce = {'status': 'started!'}
    return responce

It works only if do_something() doesn't contain threads inside.仅当 do_something() 内部不包含线程时才有效。 Please, help with the usage of async-await here 'without extra code lines'请帮助在这里使用 async-await '无需额外的代码行'

[update] this works fine only in Jupyter, but not in docker container(there yields 'RuntimeError: There is no current event loop in thread'): [更新] 这仅在 Jupyter 中有效,但在 docker 容器中无效(产生'RuntimeError:线程中没有当前事件循环'):

import asyncio

async def do_something():
    print("internal training started")
    await asyncio.sleep(5)
    print("internal training finished")

def main():
    asyncio.ensure_future(train_models())
    responce = {'status': 'started!'}
    return responce
print(main())

[update] the problem was not with threads ans asynchronous functions, the problem was with azure-functions. [更新] 问题不在于线程和异步函数,问题在于 azure-functions。 [closed] [关闭]

Using asyncio :使用asyncio

import asyncio


async def do_something():
    for i in range(10):
        print(f"Been doing expensive stuff for {i} seconds.")
        await asyncio.sleep(1)


def handle_request(request):
    task = asyncio.create_task(do_something())
    response = {request: {"status": "started!"}}
    return response, task


async def main():
    response, task = handle_request("request")
    print(response)
    await task
    print("Program finished.")


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

Output: Output:

 {'request': {'status': 'started.'}} Been doing expensive stuff for 0 seconds. Been doing expensive stuff for 1 seconds. Been doing expensive stuff for 2 seconds. Been doing expensive stuff for 3 seconds. Been doing expensive stuff for 4 seconds. Been doing expensive stuff for 5 seconds. Been doing expensive stuff for 6 seconds. Been doing expensive stuff for 7 seconds. Been doing expensive stuff for 8 seconds. Been doing expensive stuff for 9 seconds. Program finished.

Or alternatively using threading :或者使用threading

import time
from threading import Thread


def do_something():
    for i in range(10):
        print(f"Been doing expensive stuff for {i} seconds.")
        time.sleep(1)


def handle_request(request):
    thread = Thread(target=do_something)
    thread.start()
    response = {request: {"status": "started!"}}
    return response, thread


def main():
    response, thread = handle_request("request")
    print(response)
    thread.join()
    print("Program finished.")


if __name__ == "__main__":
    main()

Output: Output:

 Been doing expensive stuff for 0 seconds. {'request': {'status': 'started.'}} Been doing expensive stuff for 1 seconds. Been doing expensive stuff for 2 seconds. Been doing expensive stuff for 3 seconds. Been doing expensive stuff for 4 seconds. Been doing expensive stuff for 5 seconds. Been doing expensive stuff for 6 seconds. Been doing expensive stuff for 7 seconds. Been doing expensive stuff for 8 seconds. Been doing expensive stuff for 9 seconds. Program finished.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM