twisted学习-3 defer异步回调

defer

  1. 概念

    什么是defer?举个栗子。

    A给B打电话说:我要一份什么资料。B回答:稍等一会,等我找到了邮件给你。A在等待B的邮件的时候,他去泡了杯咖啡,吃了点东西。这时候邮件发来,A得到了他想要的资料。

    这个过程就是一个defer。

    defer下有个deferred的方法,它有如下功能

    deferred 的作用类似于“多线程”,负责保障多头连接、多项任务的异步执行。
    当然,deferred “异步”功能的实现,与多线程完全不同,具有以下特点:


    (1)deferred 产生的 event,是函数调用返回的对象;
    (2)deferred 代表一个连接任务,负责报告任务执行的延迟情况和最终结果;
    (3)对deferred 的操作,通过预定的“事件响应器”(event handler)进行。

    有了deferred,即可对任务的执行进行管理控制。防止程序的运行,由于等待某项任务的完成而陷入阻塞停滞,提高整体运行的效率。


  2. 实例

defer01.py

from twisted.internet import reactor, defer

def getDummyData(x):
    """
    工作函数
    """
    d = defer.Deferred()                                          #实例化Deferred
    reactor.callLater(2, d.callback, x * 3)                       #创建一个reactor,调用callLater方法。参数2,2秒后调用,d.callback创建回调方法,回调参数为 x * 3。这里的callLater并不是异步的回调,相当于sleep 2秒后再执行。
    return d                                                      #立即返回 回调结果d

def printData(a):                                                 #创建回调函数,形参是x
    """
    回调函数
    """
    print a

dd = getDummyData(3)                                              #实例化函数getDummyData,参数为3
dd.addCallback(printData)                                         #把回调函数printData添加到回调队里

reactor.callLater(4, reactor.stop)                                #4秒后停止事件循环器
reactor.run()                                                     #启动事件循环器

   这个代码不是很复杂,但是理解可以需要一段时间。


defer02.py        多重回调 (Multiple callbacks)

from twisted.internet import reactor, defer

class Getter:
    def getDummyData(self, x):

        self.d = defer.Deferred()
        reactor.callLater(2, self.gotResults, x)            #仍然是reactor的调用:2秒后调用函数gotResults,参数为x
        self.d.addCallback(self._toHTML)                    #添加内部函数 _toHTML 到回调队列
        return self.d

    def gotResults(self, a):

        if self.d is None:                                  #如果self.d为None,直接返回,下面的就不用处理了
            print "Nowhere to put results"
            return

        d = self.d                                          #如果self.d不为None,那么赋值给d
        self.d = None                                       #把None赋值给self.d
        if a % 2 == 0:                                      #判断奇偶
            d.callback(a*3)                                 #为偶数,回调a*3
        else:
            d.errback(ValueError("You used an odd number!"))   #奇数就报回调错误

    def _toHTML(self, r):                                 #内部回调函数

        return "Result: %s" % r

def printData(aa):                    #外部回调函数
    print aa

def printError(failure):            #外部错误回调函数
    import sys
    sys.stderr.write(str(failure))

# this series of callbacks and errbacks will print an error message
g = Getter()
d = g.getDummyData(3)
d.addCallback(printData)
d.addErrback(printError)

# this series of callbacks and errbacks will print "Result: 12"
g = Getter()
d = g.getDummyData(4)
d.addCallback(printData)
d.addErrback(printError)

reactor.callLater(4, reactor.stop)
reactor.run()

  虽然上面有我写了注释,我们还是分析下这个代码是如何运行的。

  reactor.callLater(2, self.gotResults, x)      reactor延迟2秒执行函数gotResults,然后传入参数x .

  def gotResults(self, a)  x把参数传给a,如果为偶数我们得到d.callback(a*3) 启用回调,参数是a*3.  奇数则回调错误报告函数

  然后返回队列里的函数def _toHTML(self, r),参数a*3的结果赋值给r.

  到这里,我们内部的调用完成了。

  外部还有队列 继续调用就OK了。 这就是多重继承,了解了工作方式看起来挺简单的,呵呵。(现在笑为时过早。。。)


总而言之,在twisted中。用函数来绑定defer.Deferred,再用函数来释放。这就是它的工作原理。


先写到这里吧,我艹,头疼。。。





你可能感兴趣的:(python,回调,callback,twisted)