I want to use generator yield and async functions. I read this topic, and wrote next code:
import asyncio async def createGenerator(): mylist = range(3) for i in mylist: await asyncio.sleep(1) yield i*i async def start(): mygenerator = await createGenerator() for i in mygenerator: print(i) loop = asyncio.get_event_loop() try: loop.run_until_complete(start()) except KeyboardInterrupt: loop.stop() pass
But i got the error:
SyntaxError: 'yield' inside async function
How to use yield generator in async function?
To pause execution, you need the yield keyword. When you execute the function, it returns an iterator that you can control with the next() method: 1function* fetchMovies() { 2 const data = yield fetch(); 3} 4 5const iter = fetchData(); 6iter. next(); // run the generator function up to the `yield` keyword.
The way you drive it is by using its __next__ interface (called by the python built-in function next() ). This advances the generator to the next yield statement and returns you the value of the expression to the right of yield . You can do that again and again until the generator function runs out.
Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.
Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise.
Upd:
Starting with Python 3.6 we have asynchronous generators and able to use yield
directly inside coroutines.
import asyncio async def async_generator(): for i in range(3): await asyncio.sleep(1) yield i*i async def main(): async for i in async_generator(): print(i) loop = asyncio.get_event_loop() try: loop.run_until_complete(main()) finally: loop.run_until_complete(loop.shutdown_asyncgens()) # see: https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.shutdown_asyncgens loop.close()
Old answer for Python 3.5:
You can't yield
inside coroutines. Only way is to implement Asynchronous Iterator manually using __aiter__
/__anext__
magic methods. In your case:
import asyncio class async_generator: def __init__(self, stop): self.i = 0 self.stop = stop async def __aiter__(self): return self async def __anext__(self): i = self.i self.i += 1 if self.i <= self.stop: await asyncio.sleep(1) return i * i else: raise StopAsyncIteration async def main(): async for i in async_generator(3): print(i) if __name__ == "__main__": loop = asyncio.get_event_loop() loop.run_until_complete(main())
Output:
0 1 4
Here're two more examples: 1, 2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With