Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中模仿承诺?_Python_Express_Async Await_Python Asyncio_Fastapi - Fatal编程技术网

如何在Python中模仿承诺?

如何在Python中模仿承诺?,python,express,async-await,python-asyncio,fastapi,Python,Express,Async Await,Python Asyncio,Fastapi,我在Express.js中设置了一个端点,它可以启动一个长的“for”循环,并在循环完成之前返回一个响应(我相信这要归功于将函数推送到消息队列的承诺): 但是,正如预期的那样,代码将在等待long_task()处暂停,并且仅在循环完成后返回响应。 如果我将await long_task()替换为justlong_task(),我将得到一个错误,即协程long_task从未被等待过 有没有办法在FastAPI中实现这种异步for循环,而不使用它的后台任务或芹菜之类的任务队列?与JS的unawait

我在Express.js中设置了一个端点,它可以启动一个长的“for”循环,并在循环完成之前返回一个响应(我相信这要归功于将函数推送到消息队列的承诺):

但是,正如预期的那样,代码将在
等待long_task()
处暂停,并且仅在循环完成后返回响应。 如果我将
await long_task()
替换为just
long_task()
,我将得到一个错误,即协程
long_task
从未被等待过


有没有办法在FastAPI中实现这种异步for循环,而不使用它的后台任务或芹菜之类的任务队列?

与JS的unawait
long\u task()
最接近的等价物是
asyncio.create\u task(long\u task())
。我不能100%确定
等待新承诺(…)
在JS中做了什么,但您可能想尝试
等待异步IO。创建任务(异步打印(I))
或者
等待异步打印(I);等待asyncio.sleep(0)
。(两者都会强制进行上下文切换,如果这是原始代码的要点的话。前者更接近原始代码,后者效率更高,但仍然不可取。)很难说是否有更好的方法来完成任务,因为不清楚您要处理的是什么样的长任务。为什么不喜欢使用FastAPI后台任务?未等待的协同程序会被垃圾收集,不会执行。只需将其放在后台任务中,您可以在后台运行协同程序(例如使用asyncio.gather())的同时执行任意其他操作。然后,您可以安全地返回一个已接受的201,其行为将与您的承诺相同。
const express = require('express')
const app = express()
const port = 3000

const long_task = () => {
    for (let i=0; i<100000; i++) {
        return new Promise(r => r(console.log(i)))
    }
}

app.get('/', (req, res) => {
    long_task()
    res.send('endpoint returned')
})

app.listen(port, () => {
    console.log(`Example app listening at http://localhost:${port}`)
})
async def async_print(value):
    print(value)

async def long_task():
    for i in range(10000):
        await async_print(i)

@app.get('/')
async def testing_long_task():
    await long_task()
    return 'endpoint returned'