python 同步异步回调函数讲解

先来一个比较low的回调函数示例,这里简单说下,回调其实就是一个对象,这个对象能够实例化那么我们就说可以回调,也就是简单的(*args,*kwargs)调用了

def click(func,*args,**kwargs):
    func()
    print 'callback over'

def callback():
    time.sleep(1)
    print 'i am callback'

click(callback)

运行结果如下:

i am callback
callback over

OK,这就如同一个button触发一个event似的,不过问题在于,这是同步的啊,我居然硬生生等了1S。。。这有啥意义呢,纯粹就是为了少写几个button,把所有的event当参数传递进去,一个最low的封装而已。好吧,我们现在考虑考虑如何异步执行吧

直接上代码吧:

import time
import threading

def click(func,*args,**kwargs):
    func
    print 'callback over'

def callback():
    time.sleep(3)
    print 'i am callback'
    

def anc(func):
    t = threading.Thread(target=func,args=())
    t.start()
    t.join()

click(anc(callback))

结果如下:

i am callback
callback over

结果我们依然等了3S,你以为重新开一个线程,我就不会等你了吗?

我们继续改进下呢

import time
import threading

def click(func,*args,**kwargs):
    func
    print 'callback over'

def callback():
    time.sleep(3)
    print 'i am callback'
    

def anc(func):
    t = threading.Thread(target=func,args=())
    t.start()
   # t.join() 这玩意好像引起阻塞了,我们去掉吧

click(anc(callback))

结果如下:

callback over
>>> i am callback

OK,这下没问题了,我们让我们的主线程开心的跑它的,子线程还在忙就忙它的呗,反正到时候,正常情况我们是去调别人的一个api,把我们的结果返回给它。。。很好。这下完美了。

下面问题来了,这样看上去是不是让你们觉得有点不高大上,每次调用都显得非常的麻烦,没问题,我们继续优化,是时候让我们的装饰器登场了。

import time
import threading


    
import threading
import time

def callback(func):
    def wrapper(*args, **kwargs):
        t = threading.Thread(target=func,args=())
        t.start()
    return wrapper

def click(func,*args,**kwargs):
    func()
    print "callback maybe not end,but i need tell him that i've received his command"

@callback
def event():
    time.sleep(5)
    print 'i am a event what you need now!'

@callback
def another_event():
    time.sleep(2)
    print 'i am another event you need now!'

click(event)
click(another_event)

执行结果如下:

callback maybe not end,but i need tell him that i've received his command
callback maybe not end,but i need tell him that i've received his command
1213
>>> i am another event you need now!
i am a event what you need now!

>>> 

OK,现在是不是就完美多了,更加的pythonic了!

现在新的问题来了,如果是在一个类里面呢?

同学们,你们需要思考一下了:

1 不同的线程,我们的私有变量应该如何去处理;

2 如果返回的是实时数据,我们应该如何避免管道阻塞的问题。

这一节我就不做深入讨论了,下一章讲解WSGI的api开发的时候我们再来讲解吧

发布了62 篇原创文章 · 获赞 36 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/louishu_hu/article/details/89037759