如何运行协程而不等待它?

Jac*_*k M 5 python python-asyncio

我有一个非异步函数,如下所示:

def do_stuff(on_finished):
    result = # complicated calculations here
    on_finished(result)
Run Code Online (Sandbox Code Playgroud)

我传入的回调看起来或多或少像这样:

async def on_finished(self, result):
    response = await post_over_http(result)
    self.last_status = response.status 
Run Code Online (Sandbox Code Playgroud)

当我打电话时do_stuff,我想要发生的是这样的:

  1. do_stuff执行并调用on_finished
  2. on_finished执行,通过 HTTP 发布结果,然后立即返回。
  3. do_stuff现在立即返回。
  4. 随后,HTTP 响应返回,执行返回到 的第二行on_finished

重要的是,我不希望 do_stuff 是 async。出于架构原因,我希望do_stuff与网络代码的异步性质隔离,因此我不想仅仅因为使用它的某些代码是异步的而将其设为异步。

在 JavaScript 中这不会有问题 - 基本上将上述代码直接转录为 JavaScript,我将获得所需的行为。onFinished将返回一个 Promise,它doStuff不会等待并立即返回,但是当 Promise 稍后解析时,第二行运行onFinished。这在Python中可能吗?我不确定如何实现它。通过上面的代码,我想我只是在最后一行创建了一个协程,do_stuff但从未调用它。

Tim*_*ker 8

do_stuff你可以这样设计你的函数:

def do_stuff(on_finished):
    async def _do_complicated_calculation():
        result = # do the calculation here & the post request
        await on_finished(result)
    asyncio.ensure_future(_do_complicated_calculation())
    return "ok"
Run Code Online (Sandbox Code Playgroud)

当您调用时,do_stuff(...)复杂的计算将被添加到 asyncio 事件循环中,因此它会异步执行。如果您不打算在主线程中启动事件循环,则应该让事件循环在不同的线程中运行。

由于_do_complicated_calculation()是异步的, do_stuff 将"ok"首先返回,并在计算完成后被on_finished(...)调用。