python - 在一个异步函数返回 True 后终止事件循环
问题描述
我有一个函数可以在不同的网页上查找一些信息,如果在目标网页上找到它,则返回 True,否则返回 False。我想多次调用这个函数,每次针对不同的网页,我希望它们中的每一个都异步运行,并且我希望整个过程无限循环,直到该函数的一个实例返回 True。整个代码很长,所以我将在下面对其进行简化,以便理解这一点。这段代码可以工作并且可以满足我的要求,但我想知道是否有更好或更清洁的方法来实现相同的目标。我对 asyncio 很陌生,所以请放轻松:)
import asyncio
async def find_something(loop, item_to_find, website):
while True:
# Some code to check the contents of a webpage goes here
if item_to_find in website:
loop.stop()
return True
else:
return False
loop = asyncio.get_event_loop()
try:
asyncio.ensure_future(find_something(loop, item1, website1))
asyncio.ensure_future(find_something(loop, item2, website2))
asyncio.ensure_future(find_something(loop, item3, website3))
loop.run_forever()
except Exception as e:
pass
finally:
loop.close()
编辑:我在代码中犯了一个错误,因为我只使用 print 语句进行了原始测试,在这种情况下,返回 False 会终止 while 循环并自动结束函数调用,因此函数不会无限循环。因此,需要替代解决方案的更多理由。我可以完全删除while循环并在其内部调用函数以进行递归循环,直到满足条件,或者除非满足所需条件,否则我不能返回任何内容,尽管这些听起来都不是一个好的解决方案
解决方案
我相信asyncio.as_completed
这就是你要找的。它将在每个等待完成时返回结果。
import asyncio
async def find_something(item_to_find, website):
contents = await some_code_to_check_the_contents_of_a_webpage(website)
return item_to_find in contents
async def main():
aws = [
find_something(item1, website1),
find_something(item2, website2),
find_something(item3, website3),
]
for coro in asyncio.as_completed(aws):
was_found = await coro
if was_found:
return
asyncio.run(main())
需要注意的是,无法知道find_something
返回的调用是哪个True
。如果这很重要,或者如果您需要取消任何挂起的任务,您可能希望从返回布尔值切换到返回一些可以为您提供所需信息的值(例如,参数)。然后,您可以将期货放在映射中并取消您尚未看到的任何期货。这可能看起来像
aws = {
(item1, website1): asyncio.ensure_future(item1, website1),
(item2, website2): asyncio.ensure_future(item2, website2),
(item3, website3): asyncio.ensure_future(item3, website3),
}
for coro in asyncio.as_completed(aws.values()):
item, website, was_found = await coro
del aws[item, website]
if was_found:
for future in aws.values():
future.cancel()
return
推荐阅读
- nlp - 在 spacy 中使用 glove.6B.100d.txt 嵌入得到零 lex.rank
- r - 在 Ubuntu v20.04 上的 R v4.0.1 上安装 mclust 包 v5.4.6 挂起
- python-3.x - 获取 BackgroundScheduler 作业的活动实例数
- javascript - 必须添加额外的依赖来响应 useCallback 依赖列表
- r - R中的ggplot:x轴值从99之后的原点开始
- ruby - 如果它等于特定值,则在 Ruby 中更改变量的优雅方式
- excel - Set Shape .OnAction 导致 1004 错误:应用程序定义或对象定义错误
- java - 当我从屏幕返回时调用 OnChanged ()?
- c++ - 简单的互斥保护队列与 C++ 中的线程安全队列
- node.js - 如何使用 $lookup 而不是填充