如何在Python中模仿承诺?
我在Express.js中设置了一个端点,它可以启动一个长的“for”循环,并在循环完成之前返回一个响应(我相信这要归功于将函数推送到消息队列的承诺): 但是,正如预期的那样,代码将在如何在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
等待long_task()
处暂停,并且仅在循环完成后返回响应。
如果我将await long_task()
替换为justlong_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'