Skip to content

Instantly share code, notes, and snippets.

@EddieIvan01
Created February 11, 2019 08:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EddieIvan01/76e6dc24223c34c3d3f4ea4c25ab53e2 to your computer and use it in GitHub Desktop.
Save EddieIvan01/76e6dc24223c34c3d3f4ea4c25ab53e2 to your computer and use it in GitHub Desktop.
async function decorator
from functools import wraps
from threading import Thread
from queue import Queue
class Async(object):
__slots__ = ('__result', '__task')
def __init__(self, func):
self.__result = Queue()
@wraps(func)
def wrapper(*args, **kw):
r = func(*args, **kw)
self.__result.put(r)
self.__task = wrapper
def __call__(self, *args, **kw):
thread = Thread(target=self.__task, args=args, kwargs=kw)
thread.start()
return Async.Result(self.__result, thread)
class Result(object):
def __init__(self, q, t):
self.__queue = q
self.__thread = t
def is_done(self):
return not self.__thread.is_alive()
def _get_r(self):
if not self.is_done():
raise Exception('Not done yet')
if not hasattr(self, '_result'):
self._result = self.__queue.get()
return self._result
def _set_r(self, v):
self._result = v
result = property(_get_r, _set_r)
del _get_r, _set_r
if __name__ == '__main__':
import time
import requests
@Async
def count(n):
time.sleep(n)
return f'sleep {n} done'
@Async
def http(url):
r = requests.get(url)
return r.text
start = time.time()
r1 = count(10)
r2 = count(5)
r3 = http('http://www.baidu.com')
r4 = http('http://b.cn')
for i in range(20):
print(f'call {i}')
time.sleep(1)
if r1.is_done():
print(r1.result)
if r2.is_done():
print(r2.result)
if r3.is_done():
print(r3.result)
r3.result = 'r3 done'
if r4.is_done():
print(r4.result)
r4.result = 'r4 done'
if r1.is_done() and r2.is_done() and r3.is_done() and r4.is_done():
break
end = time.time()
print(end-start)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment