Skip to content

Instantly share code, notes, and snippets.

@rayshih
Last active May 21, 2017 16:18
Show Gist options
  • Save rayshih/0908eb6bd85891d4e26ee6f391f6f937 to your computer and use it in GitHub Desktop.
Save rayshih/0908eb6bd85891d4e26ee6f391f6f937 to your computer and use it in GitHub Desktop.
from datetime import datetime
import asyncio
# The code is based on this link:
# https://www.facebook.com/photo.php?fbid=1723296854349009&set=p.1723296854349009&type=3&theater
# And of course, the output is exactly the same.
# For conveniency, I attached the output at the end of this file.
# ----- begin of polyfill -----
Await = 'await'
Yield = 'yield'
YieldFrom = 'yield_from'
AsyncFor = 'async_for'
def await_(v): return (Await, v)
def emit_(v): return (Yield, v)
def emit_from_(v): return (YieldFrom, v)
def async_for_(g, f): return (AsyncFor, (g, f))
def noop(x): pass
# the generator resolve function
def resolveAG(g, emit, done):
def step(v):
try:
if type(v) == asyncio.Task:
(t, v) = g.send(v.result())
else:
(t, v) = g.send(None)
if t == Await:
future = asyncio.ensure_future(v)
future.add_done_callback(step)
elif t == Yield:
emit(v)
step(None)
elif t == YieldFrom: # like flatten
resolveAG(v, emit, step)
elif t == AsyncFor: # like flatMap
(g2, f2) = v
def pipe(v):
g3 = f2(v)
resolveAG(g3, emit, noop)
resolveAG(g2, pipe, step)
except StopIteration:
done(None)
return
step(None)
# the runner
def runAG(g, cb):
future = asyncio.Future()
resolveAG(g, cb, future.set_result)
return future
# ----- end of polyfill -----
# ----- begin of test code -----
def counter(n):
for i in range(n):
a = yield await_(asyncio.sleep(1, "log from {}th async-gen".format(i)))
yield emit_(a)
def nested(j):
yield emit_("nested number %s" % j)
yield async_for_(counter(i - 1), nested)
def printer(n):
return runAG(counter(n), lambda i:
print('{} {}'.format(i, datetime.now())))
loop = asyncio.get_event_loop()
loop.run_until_complete(printer(5))
# Output
# log from 0th async-gen 2017-05-21 02:12:01.756030
# log from 1th async-gen 2017-05-21 02:12:02.757923
# log from 2th async-gen 2017-05-21 02:12:03.761649
# nested number log from 0th async-gen 2017-05-21 02:12:04.766404
# log from 3th async-gen 2017-05-21 02:12:05.771796
# nested number log from 0th async-gen 2017-05-21 02:12:06.774977
# nested number log from 1th async-gen 2017-05-21 02:12:07.779314
# log from 4th async-gen 2017-05-21 02:12:08.783343
# nested number log from 0th async-gen 2017-05-21 02:12:09.788776
# nested number log from 1th async-gen 2017-05-21 02:12:10.791849
# nested number log from 2th async-gen 2017-05-21 02:12:11.797282
# nested number nested number log from 0th async-gen 2017-05-21 02:12:12.800406
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment