Last active
May 21, 2017 16:18
-
-
Save rayshih/0908eb6bd85891d4e26ee6f391f6f937 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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