简体   繁体   English

使用 asyncio 运行协程后如何继续原始事件循环?

[英]How do you continue with the original event loop after running a coroutine using asyncio?

I am creating a python script that basically retrieves information from a webpage and sending a message to a discord server.我正在创建一个 python 脚本,该脚本基本上从网页中检索信息并将消息发送到 discord 服务器。

I have a main file that basically goes我有一个主要文件

import asyncio
import discord
from dotenv import load_dotenv

def update(message:str):
    load_dotenv()
    TOKEN = os.getenv('DISCORD_TOKEN')
    GUILD = os.getenv('DISCORD_GUILD')

    client = discord.Client()

    @client.event
    async def on_ready():
        for guild in client.guilds:
            if guild.name == GUILD:
                break

        print(
            f'{client.user} is connected to the following guild:\n'
            f'{guild.name}(id: {guild.id})'
        )
        updatesChannel = client.get_channel([CHANNEL 1 ID HERE])
        await updatesChannel.send(message)
    client.run(TOKEN)

def log(message:str):
    load_dotenv()
    TOKEN = os.getenv('DISCORD_TOKEN')
    GUILD = os.getenv('DISCORD_GUILD')

    client = discord.Client()

    @client.event
    async def on_ready():
        for guild in client.guilds:
            if guild.name == GUILD:
                break

        print(
            f'{client.user} is connected to the following guild:\n'
            f'{guild.name}(id: {guild.id})'
        )
        serverLogChannel = client.get_channel([CHANNEL 2 ID HERE])
        await serverLogChannel.send(message)
    client.run(TOKEN)

while True:
    text = ['Text1', 'Text2']
    channel1text = text[0]
    channel2text = text[1]
    loop = asyncio.get_event_loop()
    loop.run_until_complete( update(channel1text) )

    loop = asyncio.get_event_loop()
    loop.run_until_complete( log(channel2text) )

Currently, the script will only send the message on the first channel, but not the second channel, and it does not continue with the While loop.目前,该脚本只会在第一个通道上发送消息,而不会在第二个通道上发送消息,并且不会继续进行 While 循环。 Am I missing something here?我在这里错过了什么吗?

The core issue with your code is that client.run is a convenience synchronous function that will run the event loop, and run it forever, to keep the client going.您的代码的核心问题是client.run是一个方便的同步 function ,它将运行事件循环并永远运行,以保持客户端运行。 That is also why your update function never returns.这也是为什么您的update function 永远不会返回的原因。 Incidentally, passing a synchronous function to run_until_complete doesn't work, and if update did return, you'd get an exception and Python wouldn't proceed to the next line.顺便说一句,将同步 function 传递给run_until_complete不起作用,如果update确实返回,您会得到一个异常并且 Python 不会继续下一行。

To fix the issue, you can switch from client.run to client.start , which is async.要解决此问题,您可以从client.start切换到client.run ,这是异步的。 You can also make use of the fact that both clients connect to the same token/guild and use only one client.您还可以利用两个客户端都连接到同一个令牌/公会并仅使用一个客户端这一事实。 That way the search for the guild can be done only once, and the log and update functions can be simplified to a simple channel.send .这样公会的搜索可以只进行一次, logupdate功能可以简化为一个简单的channel.send For example (untested):例如(未经测试):

async def send_message(client, channel_id, message):
    channel = client.get_channel(channel_id)
    await channel.send(message)

async def main():
    load_dotenv()
    TOKEN = os.getenv('DISCORD_TOKEN')
    GUILD = os.getenv('DISCORD_GUILD')

    client = discord.Client()
    asyncio.create_task(client.start(TOKEN))
    await client.wait_until_ready()
    for guild in client.guilds:
        if guild.name == GUILD:
            break
    print(
        f'{client.user} is connected to the following guild:\n'
        f'{guild.name}(id: {guild.id})'
    )

    while True:
        text = ['Text1', 'Text2']
        channel1text = text[0]
        channel2text = text[1]
        await send_message(client, [CHANNEL 1 ID], channel1text)
        await send_message(client, [CHANNEL 2 ID], channel2text)

if __name__ == '__main__':
    asyncio.run(main())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 asyncio 时,如何让所有正在运行的任务在关闭事件循环之前完成 - When using asyncio, how do you allow all running tasks to finish before shutting down the event loop 如何将协程添加到正在运行的异步循环中? - how to add a coroutine to a running asyncio loop? 从事件流中运行异步协程 - Running asyncio coroutine out of the event flow 如何在运行的事件循环中添加协程? - how to add a coroutine to running event loop? Asyncio - 检查协程是否在事件循环中具有特定参数的方法? - Asyncio - way to check if coroutine with specific arguments in event loop? Python Asyncio 没有使用 asyncio.run_coroutine_threadsafe 运行新的协程 - Python Asyncio is not running new coroutine using asyncio.run_coroutine_threadsafe 使用 Python asyncio corurrent 发送网络请求时,如何让协程优先继续处理响应,而不是发送新请求? - When using Python asyncio corurrent send network request, how to make coroutine prefer continue to handle response first, not send a new request? Python 协程(Asyncio) - 如何? - Python Coroutine(Asyncio) - How to? 在 event_loop = asyncio.new_event_loop 之后不运行 asyncio.set_event_loop(event_loop) 会有什么后果(如果有的话)? - What are the consequences (if any) of not running asyncio.set_event_loop(event_loop) after event_loop = asyncio.new_event_loop? 在 asyncio 模块中,如何用我们想继续的变量跳出事件循环 - In asyncio module, how to break out of the event loop with variable we would like to continue with
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM