2

I want to use 'await' for the lambda function as shown below.

self.voice_channel.play(discord.FFmpegPCMAudio('music.mp3'), after=lambda e: await self.test(x))

SyntaxError: 'await' outside async function

How can I fix it to make it feel like this?

sanyassh
  • 8,100
  • 13
  • 36
  • 70
윤상운
  • 23
  • 1
  • 4
  • Possible duplicate of [Why can I only use the await keyword inside of async function?](https://stackoverflow.com/questions/52027030/why-can-i-only-use-the-await-keyword-inside-of-async-function) – Joao Vitorino Sep 27 '19 at 16:38

3 Answers3

3

I don't think there is a way to make a lambda async, but you can do something like:

async def temp():
    await self.test(x)

self.voice_channel.play(discord.FFmpegPCMAudio('music.mp3'), after = temp)
andole
  • 286
  • 1
  • 7
3

As the other answer said, you can't put await in a lambda. But if await is the outermost operator in the expression, you can omit both the async and await and have the lambda directly return the awaitable:

self.voice_channel.play(discord.FFmpegPCMAudio('music.mp3'),
                        after=lambda e: self.test(x))

Without the await, the lambda simply returns self.test(x). As that value was to be awaited, self.test(x) must obviously return an awaitable object. This awaitable object will be received by code that at some point invokes o.after(e) and awaits the result. In other words, await o.after(e) will be equivalent to await self.test(x), which is what you wanted to accomplish.

In general, an async def function:

async def foo():
    return await bar()

can be replaced with:

def foo():
    return bar()

Although foo() is not async in the latter case, the end result is the same: await foo() will return the result of awaiting bar(). See this answer for another example.

user4815162342
  • 141,790
  • 18
  • 296
  • 355
1

I've read the posts at the top and I did say the most recent one won't work but I don't know about the other one. But here is a easier solution to this. First off, await cannot be within a lambda expression since it isn't asyncable. Secondly, I am wondering why they're self.voice_channel and self.test. If you have the voice_channel already within the function the self needs to be omitted. Thirdly, this is my preference but add the source as a variable.

Here is my solution to this:

source = discord.FFmpegPCMAudio('music.mp3')
voice_channel.play(source, after=lambda e: asyncio.run(test(x)))

Be sure to add in the asyncio import all the way at the top:

import asyncio

Code is shorten and workable.

Tom Epsilon
  • 188
  • 6