【问题标题】:Running two loops at the same time on my discord bot在我的不和谐机器人上同时运行两个循环
【发布时间】:2021-06-11 16:13:24
【问题描述】:

所以我在 python 中的不和谐机器人有任务在用户发送消息“$start”后立即发送嵌入。在此之后,代码将启动一个 while 循环并检查用户是否做出了反应。同时我想每秒编辑一次机器人的消息,这样我就可以显示某种计时器来向用户展示他们还有多少时间做出反应,但我不知道如何实现一个同时运行的计时器。使用multiprocessing 这个有用吗? 如果有人需要它来回答我的问题,这是我非常具体的代码:)

@client.command()
async def start(ctx):
    timer = 120
    remTime = timer
    seedCapital = 10000
    sessionEmpty = True

players[ctx.author] = seedCapital

em = discord.Embed(title = "New Poker Session", description = "Waiting for players to join ...\nreact with ???? to join or ▶️ to start (only host)", color = discord.Color.green())
#em.add_field(name = "2 minutes remaining from now on!", value = "")
botMsg = await ctx.send(embed = em)
await botMsg.add_reaction("????")
await botMsg.add_reaction("▶️")

while True:
    mom0 = time.perf_counter()
    try:
        reaction, user = await client.wait_for('reaction_add', timeout = remTime, check = lambda reaction, user: reaction.emoji in ["????", "▶️"])
        #msg = await client.wait_for('message', timeout = remTime, check = lambda m: m.channel == ctx.channel)
        #print(f"receiving message: {msg.content}")
    except asyncio.TimeoutError:
        break

    if reaction.emoji == "????":
        sessionEmpty = False
        await ctx.send(f"{user.mention} joined the session!")
        players[user] = seedCapital
    elif user == ctx.author and reaction.emoji == "▶️":
        break

    mom1 = time.perf_counter()
    neededTime = mom1 - mom0
    remTime -= neededTime
    print(remTime)

if not sessionEmpty:
    await ctx.send("starting session ...")
    #start session
else:
    await ctx.send("Noone joined your session :(")

【问题讨论】:

    标签: python discord.py bots python-asyncio


    【解决方案1】:

    我们可以使用asyncio.gather来并发运行协程。

    #after command
    from datetime import datetime, timedelta
    
    end_time = datetime.now() + timedelta(seconds=30) #30 seconds to react
    
    async def coro():
       for i in range(30, 0, 5):
           await botMsg.edit(f'time remaining: {i}') #send another message if you don't want old content to be erased
           await asyncio.sleep(5)
    
    async def coro2():
       while datetime.now() <= endtime:
          #do stuff
    
    await asyncio.gather(coro(), coro2())
    

    注意:两个协程完成之间可能会有一点延迟。

    参考资料:

    编辑:这是我提到的小延迟

    【讨论】:

    • 所以我的问题是我试图在两个协程中访问相同的消息。我正在尝试 1. 等待消息的反应,2. 每秒更新消息。但是,如果我使用 asyncio.gather,我就必须创建两个单独的函数。
    • 是的,这不是问题,如果您在同一范围内定义函数,他们将可以访问所有变量,问题在于同时运行它们,这就是 asyncio.gather 所做的
    • @Toilettenbrain,它有用吗?你还卡着吗?
    猜你喜欢
    • 1970-01-01
    • 2021-07-19
    • 1970-01-01
    • 2020-09-16
    • 2021-08-04
    • 2020-10-08
    • 2021-11-18
    • 2021-06-13
    • 2020-03-26
    相关资源
    最近更新 更多