【发布时间】:2023-03-15 18:04:01
【问题描述】:
我有一个方法,它使用传递给它的 ID 从 API 获取一些数据。在此之前,ID 被放置在一个队列中,以便每个 API 调用可以使用多个(最多 100 个)。 API 调用由一个名为flush_queue 的方法执行,必须在我的程序结束时调用该方法,以保证所有添加到队列中的 ID 都已被使用。我写了一个异步函数,它接受一个 ID,创建一个 flush_queue 最终设置结果的未来,然后在可用时返回为该 ID 获得的数据:
async def get_data(self, id):
self.queued_ids.append(id)
self.results[id] = asyncio.get_running_loop().create_future()
if len(self.queued_ids) == 100:
await self.flush_queue()
return await self.results[id]
(创建并放置在results dict中的future将从flush_queue设置的该ID对应的API获取的数据作为其结果,以便可以通过上述方法返回数据。)这个在队列被刷新的情况下效果很好,因为有足够的 ID 来发出 API 请求;问题是,我需要确保在程序完成时调用flush_queue 之前将每个用户ID 添加到队列中。因此,在我这样做之前,我需要开始对get_data 的每次调用;但是,我不能等待每次调用返回的每个协程对象都完成,因为它们要等到 flush_queue 完成后才会完成。有什么办法可以确保一系列协程已经启动(但不一定完成),然后再进行调用flush_queue之类的操作?
【问题讨论】:
-
我把你的文章读了两遍,仍然不清楚你在找什么。首先,你为什么要用你已经拥有的身份创造一个未来?其次,虽然你的代码没有说明,但我猜
flush_queue是使用队列中的所有项目,但你不知道是否还有更多的项目要添加。对吗? -
@AbhijitSarkar 我正在创建一个future,因为当调用flush_queue并获得API调用的结果时,它会找到与每个ID对应的future并使用从API获取的数据调用set_result所以它可以由 get_data 返回。 flush_queue 是使用队列中的所有项目,但是当我在程序结束时调用它以确保在程序完成之前将使用所有当前排队的项目时,我知道没有更多的项目要添加。
-
虽然创建 id 的 future 似乎没有必要,但除此之外,你能不能一输入
get_data就增加一个计数器并等待它变为零?基本上,使用计数信号量。 -
@AbhijitSarkar 我很好奇,当从 API 获得的数据一次传入 100 个 id 时,您将如何发回这些数据。也就是说,计数信号量的想法是完美的,我可以简单地暂停我的主程序,直到 get_data 被输入了它被调用的次数,谢谢!
-
如何发回从 API 获得的数据 我们不要把这个问题混为一谈。如果您愿意,您可以就此提出一个新问题。我将在此处发布我之前的评论作为您的答案。
标签: python async-await python-asyncio